6–类的结构之cache

类的结构

image.png

image.png
当类第一次从磁盘加载到内存时的结构如下
image.png
第一次被使用时
image.png
将动态更新的部分提取出来,存入class_rw_ext_t
image.png

最后类的整体结构如下. ro是clean memory,从被加载之后,就不会有变化, rw是dirty memory,用于存储动态修改的
image.png

cache分析

cache 是什么

通过指针地址平移的方式在lldb中打印出cache_t的内容, 如下是cache_t的定义,本文删除了一些不必要的代码

struct cache_t {
    explicit_atomic<struct bucket_t *> _buckets;
    explicit_atomic<mask_t> _mask;
    uint16_t _flags;
    uint16_t _occupied;
    };
struct bucket_t {
private:
    explicit_atomic<SEL> _sel;
    explicit_atomic<uintptr_t> _imp;
    };
复制代码

image.png

下面是LLDB调试过程,
image.png
image.png
关于bucket_t存储到_buckets是通过hash值来存储的, 其中_occupied 指的是占用了几个,

unsigned cache_t::capacity()
{
    return mask() ? mask()+1 : 0; 
}
复制代码

_mask = _bucket的个数 -1. 继续探索_buckets是怎么存入的,在源码中找到如下方法

image.png

下面是insert的流程图
image.png

补充 isKindOfClass & isMemberOfClass

image.png
上述的结果可能会觉得比较疑惑,那么上源码
image.png
res1~res4调用的是类方法isKindOfClassisMemberOfClass

对res1分析
第一次循环tcls : 根元类, cls 是 NSObjet 不相等
第二次循环tcls:根元类的父类为NSObject 等于cls 所以res1 为YES

对res2分析
self->ISA 为根元类,与NSObject不等

对res3分析
第一次tcls:MLPerson 元类,不等
第二次tcls: MLPerson 元类的父类 为根元类,不等, 依次类推得出res3 不等

对res4分析
self->ISA 为MLPerson 元类,与MLPerson不等
复制代码
© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享