iOS Class内部结构分析
在日常开发中我们每天都要用到各种各样的Class,那么Class的内部是什么样的呢
Class的结构isa 和 superclass (如下图)
isa_t内部结构 isa_t解释图在arm64架构之前,isa就是一个普通的指针,存储着class,Meta-class的内存地址
从arm64架构开始,对isa进行了优化,变成了一个共用体(union)结构,还使用位域来存储更多的信息
使用了&Mask , |Mask 计算方式,使用了更小的内存空间,来存储更多的信息
(见下图)
cache_t cache (方法缓存)
cache_t是用散列表(哈希表)的方式来缓存曾经调用过的方法,这样可以提高方法的查找效率(空间换时间)
cache_t内部结构(左) buket_t内部结构(右)通过&_mask计算出index储存到散列表中, 如果出现哈希冲突,苹果采用的是开放定址法(线性探测再散列 index -1,只到找到空余的储存位置)来解决哈希冲突;
如果散列表长度不够,会清掉所有的缓存,以原有长度*2来扩容,重新缓存调用的方法,散列表储存为方法名(SEL):方法地址(_imp)来储存(_mask 是由散列表长度-1计算而来,如果长度改变 _mask的值也就会改变)
class_data_bits_t bits(用于获取类的信息)
bits 通过&FAST_DATA_MASK可以获取到class_rw_t这样的一个结构体(如图 Class的内部结构)
class_rw_t内部的主要内容(其他的先忽略,先说这三个)类的初始方法和类的各个分类都会用不同method_list_t(数组)所装载,比如说Peson类有n个分类,那么methods(数组)里面就有n+1个method_list_t(数组);1个Peson类的method_list_t和n个Peson分类的method_list_t;
补充:method_list_t 往 methods添加顺序是先添加分类的method_list_t,再添加原始类的method_list_t,所以在方法调用中如果分类和原始类有相同的方法,会在methods中先找到分类的方法调用,在一个类拥有多个分类的情况下,会先添加最后一个参与编译的分类,也就是说最后一个参与编译的分类里的方法实现会覆盖其他分类和原始类的方法实现;
method_t
method_t是对方法函数的封装
method_t内部结构class_ro_t
calss_ro_t里面的baseMethodList, baseProtocols ,ivars, baseProperties,是一维数组,是只读的,包含了类的初始内容
class_ro_t的内部结构Class学习总结笔记