上一篇# 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; //8字节 objc2版本中使用bits配合位域存储信息
#if defined(ISA_BITFIELD)
struct {
// 这里是定义的常量,并不会占用结构体isa_t的空间
ISA_BITFIELD; // defined in isa.h
};
#endif
};
老版本中使用cls存储指向类对象的指针,objc2版本中使用bits配合位域存储信息,这里注意位域信息ISA_BITFIELD存储在全局区,并不会占用结构体isa_t的内存空间,所以isa_t是8字节
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对象的指针
我们验证一下
实例对象、类对象、元类对象
实例对象的isa中存储指向类对象Class的指针,Class对象的isa中存储指向元类对象metaClass的指针
实例对象、类对象、元类对象的关系如下图:
简单总结
我们目前使用的objc2版本中isa除了存储指向类对象的指针以外还存储了其他信息,例如是否有关联对象,是否增在释放,引用计数等等,在老版本中isa仅仅是一个指针,并没有存储其他信息。
实例对象的isa中存储了指向类对象的指针,类对象本身也是一个实例对象,其isa中存储了指向元类对象的指针,元类对象的isa中存储了指向根元类的指针,根元类对象的isa中存储了指向自己的指针
我们在后面的文章中会探索类的结构
struct objc_class : objc_object {
// Class ISA;
Class superclass; //指向父类对象的指针
...
}
在类的结构的isa后面就是superclass,子类的superclass指针指向父类,父类的superclass指针指向NSObject,NSObject的父类指向nil。
元类也有继承关系,子类元类的superclass指针指向父类元类,父类元类的superclass指针指向根元类,根元类的superclass指针指向NSObject,NSObject的父类指向nil。
到此为止我们对isa有了一个基本的认识,后面我们会继续探索类结构的其他属性。