【iOS-RunTime系列二】isa指针

  • runTime底层的一些常用数据结构,比如isa指针;
  • arm64之前,isa就是一个普通的指针,存储着ClassMeta-Class对象的内存地址,
  • arm64开始,对isa进行了优化,变成了一个共同体 union结构, isa & ISA_MASK才得到真实地址值;
  • 看一下底层 objc_object

struct objc_object {
private:
    isa_t isa;//  32位的时候是 `Class` ,现在变成了 `union`
  • 64位开始,变成了共同体;
  • Class 、Meta-Class 对象的内存地址的二进制后3位一定是000
  • 在arm64前, isa 就是一个普通指针,存储着Class、Meta-Class对象指针;
  • arm64后,使用 union 结构,将一个64位的内存空间存储了很多内容,其中的33位存储着Class、Meta-Class对象指针地址值 ;
union isa_t 
{
        Class cls;
        uintptr_t bits; //  这是一个 unsigned long 型,
struct {
        uintptr_t nonpointer        : 1;  //  0 代表普通的指针,存储着Class、Meta-Class对象的内存地址;  1代表优化过,使用位域存储更多的信息
        uintptr_t has_assoc         : 1;  // 是否有设置过关联对象,如果没有,释放时会更快
        uintptr_t has_cxx_dtor      : 1;  //  是否有C++的析构函数,如果没有释放时会更快
        uintptr_t shiftcls          : 33; //  存储着Class、Meta-Class 对象的内存地址信息 MACH_VM_MAX_ADDRESS 0x1000000000
        uintptr_t magic             : 6;  //  用于在调度时分辨对象是否未完成初始化
        uintptr_t weakly_referenced : 1;  //  是否有被弱引用指向过,如果没有,释放会更快
        uintptr_t deallocating      : 1;  //  对象是否正在释放
        uintptr_t has_sidetable_rc  : 1;  //  里面存储的值是引用计数器减1
        uintptr_t extra_rc          : 19; //  引用计数是否过大无法存储在isa中; 如果为1,那么引用计数会存储在一个叫SideTable的类的属性中 
#       define RC_ONE   (1ULL<<45)
#       define RC_HALF  (1ULL<<18)
    };
}
  • bits是大家共用的
union {
   char bits; // 1个字节 
} _name ; 

你可能感兴趣的:(【iOS-RunTime系列二】isa指针)