跳转至

isa

isa指针是一个联合体,联合体里面有一个结构体ISA_BITFIELD。

union isa_t {
    //两个构造方法
    isa_t() { }
    isa_t(uintptr_t value) : bits(value) { }

    uintptr_t bits;

private:
    // Accessing the class requires custom ptrauth operations, so
    // force clients to go through setClass/getClass by making this
    // 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);
};

ISA_BITFIELD

里面使用了位域,优化内存

#   define ISA_BITFIELD                                                        \

            //nonPointer表示是否对isa指针开启指针优化。
            //0:纯isa指针
            //1:不止是类对象地址,isa包含类信息,对象引用计数等。
            //目的:节省内存空间
            //isa是8字节,1字节8位,所以是64位,64位里面存很多东西。以前只存类对象的内存地址,但是类对象内存地址不需要这么大内存,所以就把关于对象相关的信息包括内存地址、引用计数存在isa里面。
      uintptr_t nonpointer        : 1;                                         \

      //关联对象标志位,0没有,1存在
      uintptr_t has_assoc         : 1;                                         \

      //该对象是否有C++或者Objc等析构器,如果有析构函数,则需要做析构逻辑,如果没有,则可以更快的释放对象。
      uintptr_t has_cxx_dtor      : 1;                                         \

      //就是类对象的内存地址,存储类指针的值。
      uintptr_t shiftcls          : 44; /*MACH_VM_MAX_ADDRESS 0x7fffffe00000*/ \
      uintptr_t magic             : 6;                                         \

      //标志对象是否被指向或者曾经指向一个ARC的弱变量,没有弱引用的对象可以更快释放。(是否被`__weak`修饰)
      uintptr_t weakly_referenced : 1;                                         \
      uintptr_t unused            : 1;                                         \

      //散列表。当引用计数大于extra_rc所能存储的最大范围时,则需要借用该变量存储进位。
      uintptr_t has_sidetable_rc  : 1;                                         \

      //引用计数 最多2^8-1个,超过了就要存在散列表里面
      uintptr_t extra_rc          : 8

//64位地址空间 8字节

通过对象的isa,

每一个类都有一个isa:存储类+其它值。

对象isa和类不一样,类的isa和元类一样。

每个类:是否正在释放 引用计数 weak 关联对象 析构函数

看位域:nonPointer

如何通过isa的位运算得到类对象

通过isa右移左移右移(把其它位的清零),位移的方式就可以得到类。

也可以通过isa MASK掩码得到类。

isa的class