关联对象
objc_class中的 cache_t cache 探究
通过源码断点:x/6gx p.class
ISA 8字节
superclass 8字节
所以首字节平移16字节后就是cache的首字节地址,0x100008100 ,
然后对其强转成功输出可得:
在源码中可以看到cache的结构体是这样的
void insert(SEL sel,IMP imp,id receiver)
然后查看方法区
就可以看到insert方法 ,.既然主体是cache 那么就来看看insert方法里面的逻辑:
_maybeMask === bucket_t 长度-1
capacity === bucket_t长度 arm下为2 x86下为4
从源码可以看出,bucket_T就是用来记录方法哈希表,然后通过capacity-1 获得需要插入的数据总长,begin 就是根据插入的数据得出下标,插入的时候通过下标i 匹配出sel() 去匹配如果没有就插入imp ,当下一个sel()的fastpatch出来的值 == begin 的时候就说明这次的插入已经结束 。由此可见 这是通过一个单向循环链表去储存的,哈希表bucket_t记录缓存。
cache的扩容
在缓存插入之前有一步内存检查的操作,
在X86_64架构(Intel)下缓存大小等于3/4的时候,进行2倍扩容;
在arm64 (M!)下缓存的大小等于7/8的时,进行两倍扩容;小于8时满了就扩容
当缓存长度大于(系统设定的)默认最大值就等于默认最大值
然后才会开始缓存插入的流程
(扩容后,会把之前的桶子清理掉再继续insert)