重学OC第六篇:类结构之cache

本文深入探讨了Objective-C中的cache_t结构,分析了在模拟器和arm64真机环境下的差异,特别是关于_mask、_occupied的变化及bucket_t的数据丢失和乱序现象。通过cache::insert和cache_t::reallocate方法解析了cache的工作原理,同时介绍了散列表冲突解决的开放定址法和链表法。最后总结了cache关键属性的作用和扩容策略。
摘要由CSDN通过智能技术生成

一、cache_t分析

#if defined(__arm64__) && __LP64__
#define CACHE_MASK_STORAGE CACHE_MASK_STORAGE_HIGH_16
#elif defined(__arm64__) && !__LP64__
#define CACHE_MASK_STORAGE CACHE_MASK_STORAGE_LOW_4
#else
#define CACHE_MASK_STORAGE CACHE_MASK_STORAGE_OUTLINED
#endif

struct bucket_t {
   
    // IMP-first is better for arm64e ptrauth and no worse for arm64.
    // SEL-first is better for armv7* and i386 and x86_64.
#if __arm64__
    explicit_atomic<uintptr_t> _imp;
    explicit_atomic<SEL> _sel;
#else
    explicit_atomic<SEL> _sel;
    explicit_atomic<uintptr_t> _imp;
#endif
}

struct cache_t {
   
#if CACHE_MASK_STORAGE == CACHE_MASK_STORAGE_OUTLINED  
    explicit_atomic<struct bucket_t *> _buckets;
    explicit_atomic<mask_t> _mask;
#elif CACHE_MASK_STORAGE == CACHE_MASK_STORAGE_HIGH_16
    explicit_atomic<uintptr_t> _maskAndBuckets;
    mask_t _mask_unused;
    ......
#else
#error Unknown cache mask storage type.
#endif
    
#if __LP64__
    uint16_t _flags;
#endif
    uint16_t _occupied;

1 模拟器环境(i386、x86_64、armv7)

简化一下上面的代码,explicit_atomic的作用就是显式原子操作。

struct bucket_t {
   
	SEL _sel;
    uintptr_t _imp;
}
struct cache_t {
   
	struct bucket_t * _buckets;   //缓存的方法的SEL和IMP
   	mask_t _mask;                 //哈希掩码,开辟capacity - 1
    uint16_t _flags;			//缓存标识
    uint16_t _occupied;			//已占用的缓存空间
}

以前都是使用lldb进行内存偏移访问,今天通过打印直接访问

typedef uint32_t mask_t;  // x86_64 & arm64 asm are less efficient with 16-bits
struct gc_bucket_t {
   
    SEL _sel;
    IMP _imp;
};
struct gc_cache_t {
   
    struct gc_bucket_t *_buckets;
    mask_t _mask;
    uint16_t _flags;
    uint16_t _occupied;
};
struct gc_class_data_bits_t {
   
    uintptr_t bits;
};
struct gc_objc_class {
   
    Class ISA;
    Class superclass;
    struct gc_cache_t cache;             // formerly cache pointer and vtable
    struct gc_class_data_bits_t bits;    // class_rw_t * plus custom rr/alloc flags
};

@interface TestA : NSObject

- (void)test1;
- (void)test2;
- (void)test3;
- (void)test4;
- (void)test5;
- (void)test6;

@end

@implementation TestA

- (void)test1 {
   
    NSLog(@"TestA method name : %s", __func__);
}
- (void)test2 {
   
    NSLog(@"TestA method name : %s", __func__);
}
- (void)test3 {
   
    NSLog(@"TestA method name : %s", __func__);
}
- (void)test4 {
   
    NSLog(@"TestA method name : %s", __func__);
}
- (void)test5 {
   
    NSLog(@"TestA method name : %s", __func__);
}
- (void)test6 {
   
    NSLog(@"TestA method name : %s", __func__);
}
@end

void log_cache_t(struct gc_cache_t cache) {
   
    for (mask_t i = 0 ; i < cache._mask; i++) {
   
        // 打印获取的 bucket
        struct gc_bucket_t bucket = cache._buckets[i];
        NSLog(@"bucket._sel=%@ - bucket._imp=%p",NSStringFromSelector(bucket._sel),bucket._imp);
    }
    NSLog(@"_mask=%u, _flags=%hu, _occupied=%hu", cache._mask, cache._flags, cache._occupied);
}

int main(int argc, const char * argv[]) {
   
    @autoreleasepool {
   
        TestA *testA = [[TestA alloc] init];
        struct gc_objc_class *cls = (__bridge struct gc_objc_class *)[TestA class];
    
        log_cache_t<
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值