cache_t的结构
cache_t的缓存流程
- if (!cls->isInitialized()) return;判断类是否初始化对象,没有就直接返回。
- if (cache_getImp(cls, sel)) return;先从当前缓存查找imp,找到了就直接返回。
- cache_t *cache = getCache(cls);从当前的cls里面获取到原来的cache_t的结构体。
- cache_key_t key = getKey(sel);通过sel获取到他的key,并强转成cache_key_t类型。
- mask_t newOccupied = cache->occupied() + 1;获取当前类的occupied,并+1。
- mask_t capacity = cache->capacity();读取当前类的capacity(当前的缓存容量)。
- cache->isConstantEmptyCache():判断是否第一次,是的话就直接创建。
- newOccupied <= capacity / 4 * 3:判断newOccupied是否小于等于capacity的4分之3,是的话说明都做,不是的话就进入else,进行扩容。进入expand()。
- bucket_t *bucket = cache->find(key, receiver);通过key和传进来的receiver,找到bucket。
- if (bucket->key() == 0) cache->incrementOccupied();判断当前的bucket的key是否等于0,是的话occupied+1。
- bucket->set(key, imp);把key和imp放入bucket。
扩容代码解析:
- uint32_t oldCapacity = capacity();获取到之前的缓存容量。
- uint32_t newCapacity = oldCapacity ? oldCapacity2 : INIT_CACHE_SIZE;判断之前的容量是否有值,有的话就2,没有的话就初始化4容量
- reallocate(oldCapacity, newCapacity);创建新的缓存,并清除旧的缓存。
我们进入reallocate看下详细源码:
验证cache_t的流程
main里面的代码:
元类cache_t的验证
总结
1、OC的实例方法,是缓存在cache_t中的,类方法,则是缓存在元类中(步骤是一样的,只是要去元类中查找)。
2、cache的本质是一个Hash表
3、如果mask满了,就会进行扩容,扩容为原来的2倍-1
4、扩容的时候,会将原来的缓存清除,并不会将原来的缓存添加到新的缓存中。因为此时读写缓存不安全,同时也是为了效率最大化