文章目录
- iOS - Runtime - Class-方法缓存(cache_t)
- 1. 散列表的存取值
iOS - Runtime - Class-方法缓存(cache_t)
Class内部结构中有个方法缓存(cache_t),用散列表(哈希表)来缓存曾经调用过的方法,可以提高方法的查找速度。(使用空间换时间的方式来提升速度)

其中,_buckets就是散列表,_mask表示散列表的长度-1
哪一个
类对象调用的方法,会把该方法缓存到这个类对象。也就是说,如果class1调用的方法,最终是在他的父类或者根类才找到方法实现,也会把方法混存到class1,下次class1再调用此方法,直接在自己的方法缓存里面就能找到方法在
当前类查找,或者当前类没找到继续到父类或者跟根类,查找,都是优先从缓存里面查找,缓存没找到再到方法列表里面去查找
1. 散列表的存取值
| 0 | NULL |
|---|---|
| 1 | NULL |
| 2 | bucket_t(_key = @selector(personTest), _imp) |
| 3 | NULL |
| 4 | NULL |
| 5 | NULL |
| … | … |
_buckets就是散列表,相当于一个数组,有个初始容量- 存取数据时,假设传入的是
@selector(studentTest),使用@selector(studentTest)这个key& _mask,得出来的值作为数组的索引值,使用该索引值存取数据 @selector(studentTest) & _mask <= _mask,目的是控制得出来的索引值在数组最大容量范围之内
想象一下`&`运算后的值,一定是<= _mask
/**
0b00010101
0b00000001 <- _mask
----------------- & 运算
0b00000001
*/
&_mask生成的索引值可能一样的,怎么解决,使用索引值先取一下,判断里面的key和我们要的key是否一样,不一样(或者已存在–存值时)直接将索引值-1,还一样就继续-1,减到索引值为0时,把索引值设置为_mask,继续找,然后再-1继续找,直到找到想要的key(或者空位–存值时)- 扩容,按原来空间
2倍扩容。扩容的时候,会将缓存清掉,因为_mask的值已经变了
@oubijiexi