美文网首页
iOS 方法缓存机制cache_t

iOS 方法缓存机制cache_t

作者: 山杨 | 来源:发表于2021-11-06 00:51 被阅读0次

    类对象的数据结构

    struct objc_class : objc_object {
        // Class ISA;
        Class superclass;
        cache_t cache;             // 方法缓存
        class_data_bits_t bits;    // class_rw_t * plus custom rr/alloc flags
    };
    
    struct objc_object {
    private:
        isa_t isa;
    };
    
    其中cache_t就是方法缓存,用散列表缓存曾今调用过的方法
    struct cache_t {
      struct bucket_t *_buckets;// 散列表
      mask_t _mask;// 散列表长度 -1
      mask_t _occupied;// 已缓存的方法数量
    };
    
    struct bucket_t {
      cache_key_t _key;// SEL作为Key
      IMP _imp;// 函数内存地址
    };
    

    缓存查找方法在:源码的objc-cache.mm文件中

    struct bucket_t *_bucket;是一个散列表
    散列表(Hash table,也叫哈希表),是根据关键码值(Key value)而直接进行访问的数据结构。也就是说,它通过把关键码值映射到表中一个索引位置来访问记录,以加快查找的速度。这个映射函数叫做散列函数,存放记录的数组叫做散列表。
    给定表M,存在函数f(key),对任意给定的关键字值key,代入函数后若能得到包含该关键字的记录在表中的地址,则称表M为哈希(Hash)表,函数f(key)为哈希(Hash) 函数。

    索引位置 bucket_t
    0 Null
    1 Null
    2 bucket_t(_key = @selector(func1), _imp)
    3 bucket_t(_key = @selector(func2), _imp)
    ... ......

    SEL & _mask = 索引位置,再通过索引位置找到bucket_t,其中SEL为Key,最终找到的bucket_t为Value,计算索引位置的函数f(SEL) = SEL & _mask;被称为散列函数(也叫哈希函数)。

    • 在缓存方法的时候,通过散列函数和关键码值计算出一个索引位置,并把value放入散列表对应的索引位置处,其他还没有存放的位置全部初始化为Null;如果发现计算的索引位置已经存放了value,那么就根据自定义的规则把value存储到其他索引位置对应的value中。
    • 值得注意的是,_mask关键码值是变化的,如果当前的散列表已经存放满的时候,_mask值会扩大,同时清空原来的散列表,重新进行缓存。

    相关文章

      网友评论

          本文标题:iOS 方法缓存机制cache_t

          本文链接:https://www.haomeiwen.com/subject/sepdzltx.html