-
runTime
底层的一些常用数据结构,比如isa
指针; -
arm64
之前,isa就是一个普通的指针,存储着Class
、Meta-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 ;