nonPointerIsa

malloc的篇章里我们知道了calloc后系统根据实例变量的大小进行16字节对齐后返回了一个创建对象所需大小的内存地址,并在alloc底层源码的最后赋值给了obj,而obj此时还未和类进行关联,在经过initIsa的初始化后,obj和类能够成功的关联在一起。而 initIsa也就是对象isa的初始化。
在底层的isa其实是union isa_t 类型的结构

普遍在表现一个类的地址过程中,经常会出现一个nonPointerIsa,他不再简简单单的代表指针地址isa,因为类本身也是一个对象也可说是一个指针,而类上的很多信息是可以存储的,而一个指针占用64位单独用来存储指针是很浪费内存的,而每个类都会有isa,苹果为了优化将一些和类息息相关的信息就存储在了这64位里。例如是否正在释放、引用计数、是否有散列表、是否有析构函数、关联对象等。而要研究联合体中到底存储的什么信息就得看isa_t联合体中的位域即ISA_BITFIELD

通过源码中的宏定义发现有如下信息

nonpointer: 表示是否对isa指针开启指针优化,0: 纯isa指针,1: 不止是类对象地址,isa中包含了类信息、对象的引用计数等
has_assoc: 关联对象标志位,0 没有,1 存在
has_cxx_dtor: 该对象是否有C++或者Objc的析构函器,如果有析构函数,则需要做析构逻辑,如果没有,则可以更快的释放对象
shiftcls: 存储类指针的值。开启指针优化的情况下,在arm64架构中有33位用来存储类指针
magic: 用于调试器判断当前对象是真的对象还是没有初始化的空间
weakly_referenced: 标志对象是否被指向或者曾经指向一个ARC的弱变量,没有弱引用的对象可以更快释放
deallocationg: 标志对象是否正在释放内存
has_sidetable_rc: 当前对象引用计数大于10时,则需要借用该变量存储进位
extra_rc: 表示该对象的引用计数值,实际是引用计数值减1,如果对象的引用计数为10,那么extra_rc9,如果引用计数大于10,则需要使用has_sidetable_rc

nonPointerIsa是可以配置的如下,通过添加环境变量并设置开启或关闭的值来测试创建的对象的isa是否为nonPointerIsa,系统默认为nonPointerIsa

总结

苹果对类对象的isa指针地址进行了优化,用来存储了更多和类相关的信息这样的isa指针类型为nonPointerIsa指针。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容