This is the fifth day of my participation in Gwen Challenge

What is the ISA

A pointer to the class definition of which the object is an instance. Isa is defined as a structure in the source code


typedef struct objc_class *Class;

/// Represents an instance of a class.
struct objc_object {
    Class _Nonnull isa  OBJC_ISA_AVAILABILITY;
};

struct objc_class: objc_object {
...
}

Class isa
Copy the code

Isa is of type objc_class *, that is, a pointer. The pointer type takes 8 bytes

Initialize the isa

inline void 
objc_object::initIsa(Class cls, bool nonpointer, UNUSED_WITHOUT_INDEXED_ISA_AND_DTOR_BIT bool hasCxxDtor)
{ 
     /* TaggedPointer inline bool Objc_object ::isTaggedPointer() {return _objc_isTaggedPointer(this); } _objc_isTaggedPointer(const void * _Nullable PTR) {// The correct address of the object &_objc_tag_mask == _OBJC_TAG_MASK // ARM64 / X86_64 _OBJC_TAG_MASK (1UL<<63) // i386 _OBJC_TAG_MASK 1UL, Return ((uintptr_t) PTR & _OBJC_TAG_MASK) == _OBJC_TAG_MASK; } * /
    ASSERT(!isTaggedPointer()); 
    
    // Initialize an isa_t
    isa_t newisa(0);
    
    // Whether it is nonpointer
    if(! nonpointer) {/ / class isa
        newisa.setClass(cls, this);
    } else {
       / / the instance of the isa
        ASSERT(! DisableNonpointerIsa);ASSERT(! cls->instancesRequireRawIsa());


/ / isa_t assignment
#if SUPPORT_INDEXED_ISA
        ASSERT(cls->classArrayIndex(a) >0);
        newisa.bits = ISA_INDEX_MAGIC_VALUE;
        // isa.magic is part of ISA_MAGIC_VALUE
        // isa.nonpointer is part of ISA_MAGIC_VALUE
        newisa.has_cxx_dtor = hasCxxDtor;
        newisa.indexcls = (uintptr_t)cls->classArrayIndex(a);#else
        newisa.bits = ISA_MAGIC_VALUE;
        // isa.magic is part of ISA_MAGIC_VALUE
        // isa.nonpointer is part of ISA_MAGIC_VALUE
  #   if ISA_HAS_CXX_DTOR_BIT
        newisa.has_cxx_dtor = hasCxxDtor;
  #   endif
        newisa.setClass(cls, this);
#endif
        newisa.extra_rc = 1;
    }

    // This write must be performed in a single store in some cases
    // (for example when realizing a class because other threads
    // may simultaneously try to use the class).
    // fixme use atomics here to guarantee single-store and to
    // guarantee memory order w.r.t. the class index table
    / /... but not too atomic because we don't want to hurt instantiation
    isa = newisa;
}

Copy the code

Object ISA memory structure

Isa_t isa union. The union property isa common block of memory. The internal variables are mutually exclusive, meaning that one variable is assigned a value and the other variables have no value

union isa_t {
    isa_t() { }
    isa_t(uintptr_t value) : bits(value) { }

private:
    // private.
    
    Class cls;

public:
#if defined(ISA_BITFIELD)
    struct {
        ISA_BITFIELD;  // defined in isa.h
    };

    bool isDeallocating() {
        return extra_rc == 0 && has_sidetable_rc == 0;
    }
    void setDeallocating() {
        extra_rc = 0;
        has_sidetable_rc = 0;
    }
#endif

    void setClass(Class cls, objc_object *obj);
    Class getClass(bool authenticated);
    Class getDecodedClass(bool authenticated);
};
Copy the code

# if __arm64__ // ARM64 simulators have a larger address space, So use the ARM64e / / scheme even when simulators build for ARM64 - not - e. # if __has_feature M1 simulator (ptrauth_calls) | | TARGET_OS_SIMULATOR # define ISA_MASK 0x007ffffffffffff8ULL # define ISA_MAGIC_MASK 0x0000000000000001ULL # define ISA_MAGIC_VALUE 0x0000000000000001ULL # define ISA_HAS_CXX_DTOR_BIT 0 # define ISA_BITFIELD \ uintptr_t nonpointer : 1; \ uintptr_t has_assoc : 1; \ uintptr_t weakly_referenced : 1; \ uintptr_t shiftcls_and_sig : 52; \ uintptr_t has_sidetable_rc : 1; \ uintptr_t extra_rc : 8 # define RC_ONE (1ULL<<56) # define RC_HALF (1ULL<<7) # else // true # define ISA_MASK 0x0000000ffffffff8ULL mask # define ISA_MAGIC_MASK 0x000003f000000001ULL # define ISA_MAGIC_VALUE 0x000001a000000001ULL # define ISA_HAS_CXX_DTOR_BIT 1 # define ISA_BITFIELD \ uintptr_t nonpointer : 1; Uintptr_t has_assoc: 1; uintptr_t has_assoc: 1; // uintptr_t has_cxx_dtor: 1; // does the object have a destructor for C++ or Objc? If it has a destructor, it needs to do the destructor logic. // Store the value of the class pointer. Uintptr_t Magic: 6; // Used for debugger to judge current is real object or uninitialized space \ uintptr_t Weakly_referenced: 1; // Whether it is a weak reference, \ uintptr_t unused: 1; // Uintptr_t has_sidetable_rc: 1; // When the reference count is greater than 10, store the carry \ uintptr_t extra_rc: # define RC_ONE (1ULL<<45) # define RC_HALF (1ULL<<18) # endif # define RC_HALF (1ULL<<18) # endifCopy the code

Isa [4~37] stores classes

Explore isa through LLDB

Create an object and set a breakpoint

The object of the isa

  • As you can see from the print above, isa(–>) object –> class –> metaclass –> root metaclass –> root metaclass
  • Of the classisaSo what I’m going to store isThe metaclassYou don’t need to passmaskMask to get, only the object isnonpointer. Because only objects have reference counts, weak references, etc
  • It also follows that the class is also an object, which implies that everything is connected to objects

teacherIs inheritedperson, check through the LLDBtachertheisa

  • We can drawteachertheThe metaclassAlso points toA metaclass

Inheritance of relation to ISA

  • -> indicates that the meta indicates the metaclass
  • WLWTeacher -> WLWPerson -> NSObject -> nil
  • WLWTeacher(meta) -> WLWPerson(meta) -> NSObject(meta) -> NSobject -> nil
  • Metaclasses are also inherited, inheriting the parent metaclass to the root metaclass
  • The inherited root class of the root metaclass

Isa and inheritance of NSProxy

  • NSProxyIs to comply withNSObjectThe protocol is also the root class, so it’s the same as the NSOject root class, just the root classNSProxy
  • soNSProxywithNSObjecIt’s sibling, it’s root

Apple’s official

conclusion

  • Everything is an object, the class has only one address, so the system creates a singleton object for you, and then we create the object based on the new memory that the class inherits
  • The metaclassThere are also inheritance relationships,The metaclassinheritanceThe metaclass of the parent class
  • A metaclassinheritanceThe root class, root class inheritancenil