iOS 类03 - cache_t结构分析

184 阅读1分钟

一、探索 cache_t

类中的属性:之cache_t

1、struct objc_class : objc_object{

// Class ISA; //8字节

Class superclass; //8字节

cache_t cache; // formerly cache pointer and vtable

class_data_bits_t bits; // class_rw_t * plus custom rr/alloc flags ...

}

2、准备工作,新建一个类,声明一些方法

@interface LGPerson : NSObject
@property (nonatomic, copy) NSString *lgName;
@property (nonatomic, strong) NSString *nickName;
- (void)sayHello;
- (void)sayCode;
- (void)sayMaster;
- (void)sayNB;
@end
@implementation LGPerson
- (void)sayHello{
    NSLog(@"LGPerson say : %s",__func__);
}
- (void)sayCode{
    NSLog(@"LGPerson say : %s",__func__);
}
- (void)sayMaster{
    NSLog(@"LGPerson say : %s",__func__);
}
- (void)sayNB{
    NSLog(@"LGPerson say : %s",__func__);
}
@end

3、调用

  int main(int argc, const char * argv[]) {
    @autoreleasepool {
        // insert code here...
        LGPerson *p  = [LGPerson alloc];
        Class pClass = [LGPerson class];
//        p.lgName     = @"Cooci";
//        p.nickName   = @"KC";
        // 每调用一次。缓存一次方法 sayHello ,
        // 4
        [p sayHello];
        [p sayCode];
        [p sayMaster];
        [p sayNB1];
        [p sayNB];
            }
    return 0;
}

4、控制台打印,通过p/x pClass,找到相应的内存地址

5、cache_t 结构体

struct cache_t {
    struct bucket_t *_buckets;
    mask_t _mask;
    mask_t _occupied;
    
    ...省略代码... 
}

_buckets :存储做方法的sel 与 imp,注意:真机与rm64 中的sel 与imp顺序不一样, _mask :掩码

_occupied : 记录着类调用的方法数量

CACHE_MASK_STORAGE:架构选型,在编译的时候就被选定了。

模拟器: CACHE_MASK_STORAGE== CACHE_MASK_STORAGE_OUTLINED

真机 : CACHE_MASK_STORAGE == CACHE_MASK_STORAGE_HIGH_16

认识_buckets流程

源码分析:

总结:bucket会丢失为什么?

当bucket存储的 sel与imp,> 4/3容量的时候会重新开辟一个全新的容量为2 *INIT_CACHE_SIZE倍的内存。所以会丢失。

hash为什么会顺序会变化? mask为什么会变化? cache_t::insert{} 函数才会决定变化

cache_t总体流程:欢迎大侠们指正错误:

未完待续...