当前位置:   article > 正文

iOS Runtime面试题(说一下 Runtime 的方法缓存?存储的形式、数据结构以及查找的过程?)_ios面试方法缓存

ios面试方法缓存

说一下 Runtime 的方法缓存?存储的形式、数据结构以及查找的过程?

cache_t增量扩展的哈希表结构。哈希表内部存储的 bucket_t

bucket_t 中存储的是 SEL 和 IMP的键值对。

  • 如果是有序方法列表,采用二分查找

  • 如果是无序方法列表,直接遍历查找

cache_t结构体

  1. // 缓存曾经调用过的方法,提高查找速率
  2. struct cache_t {
  3. struct bucket_t *_buckets; // 散列表
  4. mask_t _mask; //散列表的长度 - 1
  5. mask_t _occupied; // 已经缓存的方法数量,散列表的长度使大于已经缓存的数量的。
  6. //...
  7. }
  1. struct bucket_t {
  2. cache_key_t _key; //SEL作为Key @selector()
  3. IMP _imp; // 函数的内存地址
  4. //...
  5. }

散列表查找过程,在objc-cache.mm文件中

  1. // 查询散列表,k
  2. bucket_t * cache_t::find(cache_key_t k, id receiver)
  3. {
  4. assert(k != 0); // 断言
  5. bucket_t *b = buckets(); // 获取散列表
  6. mask_t m = mask(); // 散列表长度 - 1
  7. mask_t begin = cache_hash(k, m); // & 操作
  8. mask_t i = begin; // 索引值
  9. do {
  10. if (b[i].key() == 0 || b[i].key() == k) {
  11. return &b[i];
  12. }
  13. } while ((i = cache_next(i, m)) != begin);
  14. // i 的值最大等于mask,最小等于0
  15. // hack
  16. Class cls = (Class)((uintptr_t)this - offsetof(objc_class, cache));
  17. cache_t::bad_cache(receiver, (SEL)k, cls);
  18. }

上面是查询散列表函数,其中cache_hash(k, m)是静态内联方法,将传入的keymask进行&操作返回uint32_t索引值。do-while循环查找过程,当发生冲突cache_next方法将索引值减1。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/爱喝兽奶帝天荒/article/detail/1022521
推荐阅读
相关标签
  

闽ICP备14008679号