isa详解
- 在arm64架构之前,isa就是一个普通的指针,存储着Class、Meta-Class对象的内存地址
- 从arm64架构开始,对isa进行了优化,变成了一个共用体(union)结构,还使用位域来存储更多的信息,具体结构如下
union isa_t {
isa_t() { }
isa_t(uintptr_t value) : bits(value) { }
Class cls;
uintptr_t bits;
struct {
ISA_BITFIELD; // defined in isa.h 下面是ISA_BITFIELD
uintptr_t nonpointer : 1;
uintptr_t has_assoc : 1;
uintptr_t has_cxx_dtor : 1;
uintptr_t shiftcls : 33; /*MACH_VM_MAX_ADDRESS 0x1000000000*/
uintptr_t magic : 6;
uintptr_t weakly_referenced : 1;
uintptr_t deallocating : 1;
uintptr_t has_sidetable_rc : 1;
uintptr_t extra_rc : 19
};
};
isa详解-位域
- 位域(又叫做位段)其实是一种数据结构,可以把数据以位的形式紧凑的储存,并允许程序员对此结构的位进行操作。有些信息在存储的时候,并不需要占用一个完整字节,有时候只需要占用一个或几个二进制位,比如存放一个BOOL类型的变量时,只需要保存0或1两种状态,此时只需要1个二进制位就能存储。因此,位域就是运用在这种场景下的一种数据结构,使用位域可以有效的节省存储空间。
- 位域可以把一个字节中的二进制位划分为几个不同的区域,并且制定每个区域占用的位数,每个域可以设置一个域名,可以根据域名对指定的位进行操作。
- 但是位域也有明显的缺点,就是它的内存分配和内存对齐的方式依赖于具体的机器和操作系统,不同的平台可能会有不同的结果。
- 位域的结构和结构体类似,它的形式为
struct 位域结构名称{
类型说明符 位域名 : 位域长度;
类型说明符 位域名 : 位域长度;
类型说明符 位域名 : 位域长度;
......
}
isa的结构
- isa_t作为共用体,内部使用8个字节的内存空间,共64位二进制位,存放了以下信息:
- nonpointer(1位)
0,代表普通的指针,存储着Class、Meta-Class对象的内存地址
1,代表优化过,使用位域存储更多的信息
- has_assoc(1位)
是否有设置过关联对象,如果没有,释放时会更快
- has_cxx_dtor(1位)
是否有C++的析构函数(.cxx_destruct),如果没有,释放时会更快
- shiftcls(33位)
存储着Class、Meta-Class对象的内存地址信息
- magic(6位)
用于在调试时分辨对象是否未完成初始化
- weakly_referenced(1位)
是否有被弱引用指向过,如果没有,释放时会更快
- deallocating(1位)
对象是否正在释放
- extra_rc(1位)
里面存储的值是引用计数器减1
- has_sidetable_rc(19位)
引用计数器是否过大无法存储在isa中
如果为1,那么引用计数会存储在一个叫SideTable的类的属性中
网友评论