iOS高级进阶ios面试

Runtime底层解析 - 方法缓存 :cache

2019-11-11  本文已影响0人  南城同學
struct cache_t {
    struct bucket_t *_buckets; //散列表 (bucket_t, ...)
    mask_t _mask; //散列表的长度 - 1
    mask_t _occupied; //已经缓存的方法数量
};
|
|
struct bucket_t {
    cache_key_t _key; // SEL作为Key
    IMP _imp;  //函数的内存地址
};


散列表(哈希表)

散列表找元素的原理:
应用
static inline mask_t cache_hash(cache_key_t key, mask_t mask) 
{
    return (mask_t)(key & mask);
}

_key&_mask的结果和之前的重复了怎么办 ?

即: _key&_mask 之后,该位置上已经有bucket_t了或者取出来的bucket_t_key对不上。

解决:

以存为例:

static inline mask_t cache_next(mask_t i, mask_t mask) {
    return i ? i-1 : mask;
}

如果方法过多,散列表原来的长度不够了怎么办?
void cache_t::expand()
{
    cacheUpdateLock.assertLocked();
    
    uint32_t oldCapacity = capacity();
    uint32_t newCapacity = oldCapacity ? oldCapacity*2 : INIT_CACHE_SIZE; // 2倍
     .........
   reallocate(oldCapacity, newCapacity); //里面有个" cache_collect_free(oldBuckets, oldCapacity);"
}

上一篇 下一篇

猜你喜欢

热点阅读