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, aNSObjectHow 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_tUnderstand?

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_tUnderstand?

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 yesisaPointer understanding, object understandingisaWhere does the pointer point to?isaWhat are the two types of Pointers?

Isa is equivalent to is kind of

  • Instance objectsisaPoint to class object
  • Class object refers toisaTo a metaclass object
  • Of a metaclass objectisaPoints to the base class of the metaclass

There are two types of ISA

  • A pure pointer to a memory address
  • NON_POINTER_ISAIn 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 itRuntimeMethod 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!