OC底层之isa探索

上一篇# OC底层之alloc流程探索文章我们探索了一下alloc的流程,其中涉及到了很多isa相关的内容我们将在这里进行探索

在上文中创建isa的方法是

inline void 

objc_object::initIsa(Class cls, bool nonpointer, bool hasCxxDtor) 
{ 
        ...
        isa_t newisa(0);
        ...
}
复制代码

isa_t

union isa_t {
    isa_t() { }
    isa_t(uintptr_t value) : bits(value) { }

    // 老版本中isa只是一个指针
    Class cls;
    uintptr_t bits;
#if defined(ISA_BITFIELD)
    // objc2版本中使用联合体位域存储信息
    struct {
        ISA_BITFIELD;  // defined in isa.h
    };
#endif
};
复制代码

ISA_BITFIELD

# elif __x86_64__
#   define ISA_MASK        0x00007ffffffffff8ULL
二进制为:0b0000000000000000011111111111111111111111111111111111111111111000
#   define ISA_MAGIC_MASK  0x001f800000000001ULL
二进制为:0b0000000000011111100000000000000000000000000000000000000000000001
#   define ISA_MAGIC_VALUE 0x001d800000000001ULL
二进制为:0b0000000000011101100000000000000000000000000000000000000000000001
#   define ISA_BITFIELD
      // nonpointer为1表示isa不光存储指针还存储其他信息,
      // 例如是否正在释放,是否有关联对象等等
      uintptr_t nonpointer        : 1; 
      
      // 是否有关联对象
      uintptr_t has_assoc         : 1;                         
      
      // 是否有c++析构函数
      uintptr_t has_cxx_dtor      : 1;                         
      
      // 存储指向类对象的指针
      uintptr_t shiftcls          : 44; /*MACH_VM_MAX_ADDRESS 0x7fffffe00000*/ 
      
      // 标识当前对象有没有初始化
      uintptr_t magic             : 6;                         
      
      // 是否有关联的weak指针
      uintptr_t weakly_referenced : 1;                         
      
      // 是否正在释放
      uintptr_t deallocating      : 1;                        
      
      // 引用计数是否存在外面sidetable中
      uintptr_t has_sidetable_rc  : 1;                        
      
      // 存储引用计数
      uintptr_t extra_rc          : 8
#   define RC_ONE   (1ULL<<56)
#   define RC_HALF  (1ULL<<7)
复制代码

isa大小为64位,既8字节的联合体union,因为系统是8字节对齐的,所以低三位为0,从第四位开始存储指向Class对象的指针

image.png

我们验证一下

image.png

实例对象、类对象、元类对象

实例对象的isa中存储指向类对象Class的指针,Class对象的isa中存储指向元类对象metaClass的指针

image.png

实例对象、类对象、元类对象的关系如下图:

da435341f46a446d91b7e338f0a835fc_tplv-k3u1fbpfcp-watermark.webp

简单总结

我们目前使用的objc2版本中isa除了存储指向类对象的指针以外还存储了其他信息,例如是否有关联对象,是否增在释放,引用计数等等,在老版本中isa仅仅是一个指针,并没有存储其他信息。

实例对象的isa中存储了指向类对象的指针,类对象本身也是一个实例对象,其isa中存储了指向元类对象的指针,元类对象的isa中存储了指向根元类的指针,根元类对象的isa中存储了指向自己的指针

我们在后面的文章中会探索类的结构

struct objc_class : objc_object {
    // Class ISA;
    Class superclass; //指向父类对象的指针
    ...
}
复制代码

在类的结构的isa后面就是superclass,子类的superclass指针指向父类,父类的superclass指针指向NSObjectNSObject的父类指向nil

元类也有继承关系,子类元类的superclass指针指向父类元类,父类元类的superclass指针指向根元类,根元类的superclass指针指向NSObjectNSObject的父类指向nil

到此为止我们对isa有了一个基本的认识,后面我们会继续探索类结构的其他属性。

参考文章

# isa的初始化&指向分析

猜你喜欢

转载自juejin.im/post/7019220638606819336