What is the isa pointer to an objc object? What does it do?
Points to his class object so that you can find methods on that object
Best Answer: The following diagram illustrates the relationship between objects, classes, and metaclasses:
The solid line is the super_class pointer and the dotted line is the ISA pointer.
1.Root class(class) is really NSObject, and NSObject has no superclass, so the superclass of Root class(class) points to nil. 2. Each Class has an ISA pointer to a unique Meta Class. 3. The superclass of Root Class (Meta) points to Root Class (Class), which is NSObject, forming a loop. 4. Isa pointer to each Meta class points to Root class (Meta).
2, aNSObject
How much memory does an object take up?
Due to the memory allocation mechanism, an NSObject object is allocated 16 bytes of memory.
But in fact, in 64-bit, only 8 bytes are used; In 32 bits, only 4 bytes were used
The size of a member variable of an NSObject instance object is actually 8 bytes
#import <Objc/Runtime>
Class_getInstanceSize([NSObject Class])
Copy the code
Nature is
size_t class_getInstanceSize(Class cls)
{
if(! cls)return 0;
return cls->alignedInstanceSize();
}
Copy the code
Gets the size of memory pointed to by the Obj -c pointer, which is actually 16 bytes
#import <malloc/malloc.h>
malloc_size((__bridge const void *)obj);
Copy the code
Object memory is aligned when allocating memory, so in iOS, memory is allocated in multiples of 16 bytes.
Can through the following url: openSource.apple.com/tarballs to view the source code.
3. Say yesclass_rw_t
Understand?
Rw stands for readable and writable.
The attributes, methods, and protocols of ObjC classes are stored in class_rw_t:
// Can read and write
struct class_rw_t {
// Be warned that Symbolication knows the layout of this structure.
uint32_t flags;
uint32_t version;
const class_ro_t *ro; // Point to a read-only structure that holds initial class information
/* These three arrays are both readable and writable, containing the initial contents of the class and the contents of the class. Method_list_t ----> method_t and method_list_t --> method_t are partially merged from class_ro_t. * /
method_array_t methods; // List of methods (class objects store object methods, metaclass objects store class methods)
property_array_t properties; // Attribute list
protocol_array_t protocols; // Protocol list
Class firstSubclass;
Class nextSiblingClass;
/ /...
}
Copy the code
4. Say yesclass_ro_t
Understand?
Stores properties, methods, and protocols that were identified at compile time for the current class.
struct class_ro_t {
uint32_t flags;
uint32_t instanceStart;
uint32_t instanceSize;
uint32_t reserved;
const uint8_t * ivarLayout;
const char * name;
method_list_t * baseMethodList;
protocol_list_t * baseProtocols;
const ivar_list_t * ivars;
const uint8_t * weakIvarLayout;
property_list_t *baseProperties;
};
Copy the code
BaseMethodList, baseProtocols, Ivars, and baseProperties are all primitive arrays.
5. Say yesisa
Pointer understanding, object understandingisa
Where does the pointer point to?isa
What are the two types of Pointers?
Isa is equivalent to is kind of
- Instance objects
isa
Point to class object - Class object refers to
isa
To a metaclass object - Of a metaclass object
isa
Points to the base class of the metaclass
There are two types of ISA
- A pure pointer to a memory address
NON_POINTER_ISA
In addition to the memory address, there is some other information
Isa source code analysis
See the Runtime source for isa_t as a Commons. The simplified structure is as follows:
union isa_t
{
Class cls;
uintptr_t bits;
# if __arm64__ // arm64 architecture
# define ISA_MASK 0x0000000ffffffff8ULL // To fetch 33 bits of memory address using the (&) operation
# define ISA_MAGIC_MASK 0x000003f000000001ULL
# define ISA_MAGIC_VALUE 0x000001a000000001ULL
struct {
uintptr_t nonpointer : 1; //0: indicates a common pointer. 1: indicates an optimized pointer that can store more information.
uintptr_t has_assoc : 1; // Whether the associated object is set. If not, the release will be faster
uintptr_t has_cxx_dtor : 1; // is there a C++ destructor
uintptr_t shiftcls : 33; // MACH_VM_MAX_ADDRESS 0x1000000000 Memory address value
uintptr_t magic : 6; // Used to tell if an object is not initialized during debugging
uintptr_t weakly_referenced : 1; // If there is a weak reference to point to
uintptr_t deallocating : 1; // Whether is being released
uintptr_t has_sidetable_rc : 1; // Whether the reference counter is too large to be stored in ISA. If it is 1, the reference count is stored in an attribute of a class called SideTable
uintptr_t extra_rc : 19; // The value stored inside refers to the counter decrement by 1
# define RC_ONE (1ULL<<45) # define RC_HALF (1ULL<<18) }; # define ISA_MASK 0x00007ffffFFFF8ull # define ISA_MAGIC_MASK # define ISA_MAGIC_MASK 0x001f800000000001ULL # define ISA_MAGIC_VALUE 0x001d800000000001ULL struct { uintptr_t nonpointer : 1; uintptr_t has_assoc : 1; uintptr_t has_cxx_dtor : 1; uintptr_t shiftcls : 44; // MACH_VM_MAX_ADDRESS 0x7fffffe00000 uintptr_t magic : 6; uintptr_t weakly_referenced : 1; uintptr_t deallocating : 1; uintptr_t has_sidetable_rc : 1; uintptr_t extra_rc : 8; # define RC_ONE (1ULL<<56) # define RC_HALF (1ULL<<7) }; # else # error unknown architecture for packed isa # endif }Copy the code
Note: What is a bitfield?
6. Talk about itRuntime
Method cache? The form of storage, data structure, and search process?
The hash table structure for cache_t incremental extensions. The bucket_t stored internally in the hash table.
Bucket_t stores SEL and IMP key-value pairs.
-
For an ordered list of methods, use binary lookup
-
If it’s an unordered list of methods, just walk through the search
Cache_t structure
// Cache the methods that have been called to improve the search speed
struct cache_t {
struct bucket_t *_buckets; / / a hash table
mask_t _mask; // Hash table length -1
mask_t _occupied; // The number of cached methods, the length of the hash table should be greater than the number of cached methods.
/ /...
}
Copy the code
struct bucket_t {
cache_key_t _key; //SEL as key@selector ()
IMP _imp; // The memory address of the function
/ /...
}
Copy the code
Hash table lookup procedure, in objc-cache.mm file
// query hash table, k
bucket_t * cache_t::find(cache_key_t k, idreceiver) { assert(k ! =0); / / assertions
bucket_t *b = buckets(); // Get the hash table
mask_t m = mask(); // Hash table length -1
mask_t begin = cache_hash(k, m); / / & operation
mask_t i = begin; / / index value
do {
if (b[i].key() == 0 || b[i].key() == k) {
return&b[i]; }}while((i = cache_next(i, m)) ! = begin);// the value of I is mask at most and 0 at least.
// hack
Class cls = (Class)((uintptr_t)this - offsetof(objc_class, cache));
cache_t::bad_cache(receiver, (SEL)k, cls);
}
Copy the code
Cache_hash (k, m) is a static inline method that uses &of the key and mask passed in to return the uint32_t index. The do-while loop finds the process by which the cache_next method decrement the index value by one when a conflict occurs.
Those iOS development common bottom level questions collection!