iOS|iOS Runtime 的方法缓存(存储的形式、数据结构以及查找的过程?)
Runtime一部分源码
struct objc_class : objc_object {
// Class ISA;
Class superclass;
cache_t cache;
// formerly cache pointer and vtable
class_data_bits_t bits;
// class_rw_t * plus custom rr/alloc flagsclass_rw_t *data() {
return bits.data();
}
void setData(class_rw_t *newData) {
bits.setData(newData);
}
}
cache_t结构体
// 方法缓存结构体
struct cache_t {
// 存储被缓存方法的哈希表
struct bucket_t *_buckets;
// 占用的总大小
mask_t _mask;
// 已使用大小
mask_t _occupied;
public:
struct bucket_t *buckets();
mask_t mask();
mask_t occupied();
void incrementOccupied();
void setBucketsAndMask(struct bucket_t *newBuckets, mask_t newMask);
void initializeToEmpty();
mask_t capacity();
bool isConstantEmptyCache();
bool canBeFreed();
static size_t bytesForCapacity(uint32_t cap);
static struct bucket_t * endMarker(struct bucket_t *b, uint32_t cap);
void expand();
void reallocate(mask_t oldCapacity, mask_t newCapacity);
struct bucket_t * find(cache_key_t key, id receiver);
static void bad_cache(id receiver, SEL sel, Class isa) __attribute__((noreturn));
};
struct bucket_t {
private:
cache_key_t _key;
////SEL作为Key @selector()
IMP _imp;
// 函数的内存地址public:
inline cache_key_t key() const { return _key;
}
inline IMP imp() const { return (IMP)_imp;
}
inline void setKey(cache_key_t newKey) { _key = newKey;
}
inline void setImp(IMP newImp) { _imp = newImp;
}void set(cache_key_t newKey, IMP newImp);
};
查找过程,在objc-cache.mm文件中
bucket_t * cache_t::find(cache_key_t k, id receiver)
{
assert(k != 0);
// 断言bucket_t *b = buckets();
// 获取散列表
mask_t m = mask();
// 散列表长度 - 1
mask_t begin = cache_hash(k, m);
// & 操作
mask_t i = begin;
// 索引值
do {
if (b[i].key() == 0||b[i].key() == k) {
return &b[i];
}
} while ((i = cache_next(i, m)) != begin);
// i 的值最大等于mask,最小等于0。// hack
Class cls = (Class)((uintptr_t)this - offsetof(objc_class, cache));
cache_t::bad_cache(receiver, (SEL)k, cls);
}
总结 Runtime 的方法缓存? cache_t哈希表结构。哈希表内部存储的 bucket_t。
存储的形式、数据结构 bucket_t 中存储的是 SEL 和 IMP的键值对。
以及查找的过程? 【iOS|iOS Runtime 的方法缓存(存储的形式、数据结构以及查找的过程?)】如果是有序方法列表,采用二分查找
如果是无序方法列表,直接遍历查找
推荐阅读
- 热闹中的孤独
- JAVA(抽象类与接口的区别&重载与重写&内存泄漏)
- 放屁有这三个特征的,请注意啦!这说明你的身体毒素太多
- 一个人的旅行,三亚
- 布丽吉特,人生绝对的赢家
- 慢慢的美丽
- 尽力
- 一个小故事,我的思考。
- 家乡的那条小河
- 《真与假的困惑》???|《真与假的困惑》??? ——致良知是一种伟大的力量