Cache
缓存可以提高代码运行效率以达到优化的效果,在runtime 的学习中就有涉及到 Cache的部分通过源码分析可以学习 苹果是怎么做的
WDClassInfo不知道咋传
需要这个东西 主要是仿Class 的结构山寨的。然后把
要分析的Class 赋值给 这个仿的Clas 可以看出一些东西
首先了解 runtime中 objc_class 的结构
cache_t 结构体
bucket_t 结构体
结构差不多就是这样
1 | 初始都为NULL 当有缓存方法插入 才会插入 bucket_t |
---|---|
2 | NULL |
3 | NULL |
4 | bucket_t(key = @Selector(test),imp) |
5 | NULL |
6 | NULL |
既然是散列表 是怎么计算缓存方法存在那呢 总不能一个一个便利吧
苹果使用的是 @selector(test) & _mask(散列表长度) 得出值存在响应的位置
比如 0000 1010 & 0000 0011 & 操作 两个都是1才返回1 否则返回0 所以 得到的值是不会大于 要&上的值 就是不会大于 0000 0011
在缓存创建的时候会给一个固定空间大小 存满了 不够了会调用 expand 来扩容
比如一开始给了3 满了 把之前的清掉 然后扩容重新继续添加
查找缓存
- 运行看看效果 是不是和猜想一样 创建一个类 Home
@interface Home : NSObject
- (void)say;
- (void)sayHello;
- (void)sayHelloWord;
- (void)sayGoodIdea;
- (void)sayHaha;
- (void)sayWahaha;
- (void)sayBaba;
@end
@implementation Home
- (void)say{}
- (void)sayHello{}
- (void)sayHelloWord{}
- (void)sayGoodIdea{}
- (void)sayHaha{}
- (void)sayWahaha{}
- (void)sayBaba{}
@end
然后 main.mm中添加
int main(int argc, const char * argv[]) {
// 整个程序都包含在一个@autoreleasepool中
@autoreleasepool {
Home *h = [[Home alloc]init];
wd_objc_class *goodStudentClass = (__bridge wd_objc_class *)[Home class];
[h say];
//[h sayHello];
//[h sayHelloWord];
//[h sayGoodIdea];
//[h sayHaha];
//[h sayWahaha];
//[h sayBaba];
}
return 0;
}
图里可见 home 初始化 又调用了个say方法 散列表长度 3 然后已经把 say 和init 插到了 表中 那如果超过三个会发生什么变化 看下图
刚刚好存满 再添加一个 接下来是重点
超过三个 触发了扩容的方法 清空之前的缓存 并添加了新的 sayHelloWord 进入缓存列表 那再看看7个也满了是不是继续阔
待续