在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
存储对象的引用计数,值为引用计数器减一,因为在获取对象的引用计数的方法中,系统会做加一处理。