Runtime源码理解isa

在arm64架构之前,isa就是一个普通的指针,存储着Class、Meta-Class对象的内存地址。
在Runtime源码中可以看到

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

从arm64架构开始,对isa进行了优化,变成了一个共用体(unit)结构,还使用位域来存储更多的信息
在Runtime源码中可以看到

struct objc_object {
private:
    isa_t isa;
}
//共用体中可以定义多个成员,共用体的大小由最大的成员大小决定
//共用体的成员公用一个内存
//对某一个成员赋值,会覆盖其他成员的值
//存储效率更高
union isa_t 
{
    isa_t() { }
    isa_t(uintptr_t value) : bits(value) { }
    Class cls;
    uintptr_t bits;   //存储下面结构体每一位的值
#if SUPPORT_PACKED_ISA
# if __arm64__
#   define ISA_MASK        0x0000000ffffffff8ULL
#   define ISA_MAGIC_MASK  0x000003f000000001ULL
#   define ISA_MAGIC_VALUE 0x000001a000000001ULL
    struct {
        uintptr_t nonpointer        : 1;
        uintptr_t has_assoc         : 1;
        uintptr_t has_cxx_dtor      : 1;
        uintptr_t shiftcls          : 33; // MACH_VM_MAX_ADDRESS 0x1000000000
        uintptr_t magic             : 6;
        uintptr_t weakly_referenced : 1;
        uintptr_t deallocating      : 1;
        uintptr_t has_sidetable_rc  : 1;
        uintptr_t extra_rc          : 19;
#       define RC_ONE   (1ULL<<45)
#       define RC_HALF  (1ULL<<18)
    };
}

nonpointer

表示是否对 isa 指针开启指针优化
0:表示普通指针,存储着Class、Meta-Class对象的内存地址
1:表示优化过的指针,使用位域存储更多的信息,包含是否有关联对象、对象的引用计数、是否有弱引用、是否使用C++代码等等。

has_assoc

关联对象标志位,0没有,1存在
是否有设置过关联对象,关联对象被取消,值任然为1

has_cxx_dtor

是否有C++的析构函数 0 没有,对象释放时会更快 1 有 需要做析构的逻辑处理

shiftcls

存储着Class、Meta-Class对象的内存地址

magic

用于调试器判断当前对象是真的对象还是没有初始化的空间

weakly_referenced

是否设置过被弱引用指向过 0 没有,对象释放时会更快 1 有,对象释放时,runtime会将所以指向该对象的弱引用置为nil,
只要被弱引用指向过,其值就是1

deallocating

标志对象是否正在释放内存

has_sidetable_rc

是否有外挂的引用计数表, 0 没有 1 有,当对象的引用计数大于10是,则需要外挂引用计数表来管理对象

extra_rc

存储对象的引用计数,值为引用计数器减一,因为在获取对象的引用计数的方法中,系统会做加一处理。

你可能感兴趣的:(Runtime源码理解isa)