类的结构
当类第一次从磁盘加载到内存时的结构如下
第一次被使用时
将动态更新的部分提取出来,存入class_rw_ext_t
最后类的整体结构如下. ro
是clean memory,从被加载之后,就不会有变化, rw
是dirty memory,用于存储动态修改的
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;
};
复制代码
下面是LLDB调试过程,
关于bucket_t
存储到_buckets
是通过hash
值来存储的, 其中_occupied
指的是占用了几个,
unsigned cache_t::capacity()
{
return mask() ? mask()+1 : 0;
}
复制代码
_mask = _bucket的个数 -1
. 继续探索_buckets
是怎么存入的,在源码中找到如下方法
下面是insert的流程图
补充 isKindOfClass & isMemberOfClass
上述的结果可能会觉得比较疑惑,那么上源码
res1~res4
调用的是类方法isKindOfClass
和 isMemberOfClass
对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