问题/目标分析
分析NSObject 底层数据 cache_t 信息
方法分析
通过源码,lldb x/4xg 命令,打印内存中cache_t信息
实验步骤
1、打印cache_t中 bucket_t信息
执行walk 方法之前。
使用类型强转直接打印内容
typedef uint32_t mask_t;
typedef uintptr_t cache_key_t;
typedef unsigned long uintptr_t;
//注意mac和iphone的定义顺序不一样,根据机型更换顺序
struct lg_bucket_t {
IMP _imp;
cache_key_t _key;
};
struct lg_cache_t {
struct lg_bucket_t *_buckets;
mask_t _mask;
mask_t _occupied;
};
struct lg_class_data_bits_t {
uintptr_t bits;
};
struct lg_objc_class {
Class ISA;
Class superclass;
struct lg_cache_t cache; // formerly cache pointer and vtable
struct lg_class_data_bits_t bits; // class_rw_t * plus custom rr/alloc flags
};
+(void)testStruct
{
LGPerson *person = [[LGPerson alloc] init];
Class pClass = [LGPerson class];
// cache_t 为什么没有 - 第一次
[person sayHello];
[person sayCode];
// [person sayNB];
struct lg_objc_class *lg_pClass = (__bridge struct lg_objc_class *)(pClass);
for (mask_t i = 0; i<lg_pClass->cache._mask; i++) {
struct lg_bucket_t bucket = lg_pClass->cache._buckets[i];
NSLog(@"%lu - %p",bucket._key,bucket._imp);
}
NSLog(@"%@ - %p",person,pClass);
}
结果
结果分析
cache_t是一个缓存方法的列表,从中可以找到近期运行的方法。
bucket 为 sel-imp对应字典
mask 为总缓存大小-1
occupied 为当前缓存区使用大小
当缓存区到达最大缓存的3/4时,清空缓存,缓存大小翻倍。
总结实验
从cache_t可以知道类型近期调用的方法,也是方法查找加速的一个工具,增加其大小可以增加缓存命中。