什么是isa?
每个对象都是从NSObject类继承的isa实例变量来连接到运行时系统。 它指向从类定义编译的结构。 通过isa,对象可以找到运行时所需的任何信息,例如其在继承层次结构中的位置,其实例变量的大小和结构以及可以响应消息执行的方法实现的位置。
isa的结构
1、isa就是isa_t,且isa是个联合体位域。
2、isa_t() { }:单纯的初始化
3、isa_t(uintptr_t value) : bits(value) { }:也是单纯的初始化,只不过这个有传值,和2相同
4、Class cls:绑定关联一个class(其实就是class和isa绑定在一起)
5、bits:决定联合体的长度,并且对位域ISA_BITFIELD(bits和上面的cls是互斥的,赋值了cls就不出创建bits)
6、ISA_BITFIELD:结构如下
arm64:
nonpointer:表示是否对 isa 指针开启指针优化 0:纯isa指针,1:不止是类对象地址,isa 中包含了类信息、对象的引用计数等。
has_assoc:关联对象标志位,0没有,1存在。
has_cxx_dtor:该对象是否有 C++ 或者 Objc的析构器,如果有析构函数,则需要做析构逻辑,如果没有,则可以更快的释放对象。
shiftcls: 存储类指针的值。开启指针优化的情况下,在arm64架构中有33位用来存储类指针,x86_64则用44位存储。
magic:用于调试器判断当前对象是真的对象还是没有初始化的空间
weakly_referenced:志对象是否被指向或者曾经指向一个 ARC 的弱变量, 没有弱引用的对象可以更快释放。
deallocating:标志对象是否正在释放内存
has_sidetable_rc:当对象引用技术大于 10 时,则需要借用该变量存储进位
extra_rc:当表示该对象的引用计数值,实际上是引用计数值减 1, 例如,如果对象的引用计数为 10,那么 extra_rc 为 9。如果引用计数大于 10, 则需要使用到下面的 has_sidetable_rc。
isa的初始化
我们通过initIsa进入到初始化isa的详细代码中看看。
2、x/4xg per:然后我们打印出per的地址信息,第一个地址必然是isa。
3、p/x 0x001d800100001129 & 0x00007ffffffffff8:我们用isa的地址&掩码,就得到了我们第一行的地址。由此可见,isa&掩码之后就和类关联起来了。
元类
首先我们要明白一个叫元类的类:它是由系统在创建一个类的时候,为了在后期的便捷,就会创建一个叫元类的类。既元类就是类对象所属的类(元类的定义和创建都是编译器自动完成的,无需人为干涉)。