isa分为POINTER_ISA(指针类型)和NONPOINTER_ISA(非指针类型)
POINTER_ISA指针类型只有一个内存地址
NONPOINTER_ISA除了有地址,还包含其他字段:
//arm64 架构
struct
{
uintptr_t nonpointer : 1; // 0:普通指针,1:优化过,使用位域存储更多信息
uintptr_t has_assoc : 1; // 对象是否含有或曾经含有关联引用,如果没有,则析构时会更快
uintptr_t has_cxx_dtor : 1; // 表示是否有C++析构函数或OC的dealloc,如果没有,则析构时会更快
uintptr_t shiftcls : 33; // 类的指针,存放着 Class、Meta-Class 对象的内存地址信息
uintptr_t magic : 6; // 固定值为 0xd2,用于在调试时分辨对象是否未完成初始化
uintptr_t weakly_referenced : 1; // 是否被弱引用指向,如果没有,则析构时更快
uintptr_t deallocating : 1; // 对象是否正在释放
uintptr_t has_sidetable_rc : 1; // 是否需要使用 sidetable 来存储引用计数
uintptr_t extra_rc : 19; // 引用计数能够用 19 个二进制位存储时,直接存储在这里
};
has_sidetable_rc表明该对象的引用计数器是否过大而无法储存到isa指针,如果过大,则其会存入相应的sideTable(散列表)中,正常则存入extra_rc中,且extra_rc保存的是引用计数减1后的结果