【iOS底层】06:cache_t分析

本文详细分析了iOS中cache_t的数据结构,通过LLDB验证其组成,探讨了bucketsAndMaybeMask、_occupied等字段的作用。文章揭示了cache_t采用的无序hash链表存储方式,以及在达到容量3/4时的扩容机制。同时,讨论了为什么不直接添加新元素,而是清空后再扩容的原因,以及buckets()函数与_bucketsAndMaybeMask的关系。最后,概述了cache的读取流程和insert时机。
摘要由CSDN通过智能技术生成
struct objc_class : objc_object {
// Class ISA;
    Class superclass;
    cache_t cache;             // formerly cache pointer and vtable
    class_data_bits_t bits; 
}

在分析完了类里的ISA,bits以后,我们来看下另一块比较重要的--cache。

一、cache_t数据结构分析

  •  我们先从源码来看下cache_t的数据结构:
struct cache_t {
private:
    explicit_atomic<uintptr_t> _bucketsAndMaybeMask; // 8
    union {
        struct {
            explicit_atomic<mask_t>    _maybeMask; // 4
#if __LP64__
            uint16_t                   _flags;  // 2
#endif
            uint16_t                   _occupied; // 2
        };
        explicit_atomic<preopt_cache_t *> _originalPreoptCache; // 8
    };
    //省略剩余部分...
}

我们先来按照bits的方法,在lldb中看下cache数据
我们在LGPerson类中声明一个对象方法 - (void)saySomething;
并在main函数中调用一下

LGPerson *p = [LGPerson alloc];
[p saySomething];
(lldb) p/x pClass //获取类的首地址
(Class) $1 = 0x0000000100008400 LGPerson
(lldb) p (cache_t *)0x0000000100008410 //首地址平移16字节获取cache
(cache_t *) $2 = 0x0000000100008410
(lldb) p *$2 //查看cache值内容
(cache_t) $3 = {
  _bucketsAndMaybeMask = {
    std::__1::atomic<unsigned long> = {
      Value = 4298515408
    }
  }
   = {
     = {
      _maybeMask = {
        std::__1::atomic<unsigned int> = {
          Value = 0
        }
      }
      _flags = 32808
      _occupied = 0
    }
    _originalPreoptCache = {
      std::__1::atomic<preopt_cache_t *> = {
        Value = 0x0000802800000000
      }
    }
  }
}
(lldb) p [p saySomething]  //上边value没有值是因为我们没有调用方法,没有缓存,调用一下
2021-06-25 14:22:15.679137+0800 KCObjcBuild[57009:1207201] -[LGPerson saySomething]
(lldb) p *$2
(cache_t) $4 = {
  _bucketsAndMaybeMask = {
    std::__1::atomic<unsigned long> = {
      Value = 4301537696
    }
  }
   = {
     = {
      _maybeMask = {
        std::__1::atomic<unsigned int> = {
          Value = 7
        }
      }
      _flags = 32808
      _occupied = 1
    }
    _originalPreoptCache = {
      std::__1::atomic<preopt_cache_t *> = {
        Value = 0x0001802800000007
      }
    }
  }
}

上边在cache里我们看到了几个值,
_bucketsAndMaybeMask
_maybeMask
_flags
_occupied
_originalPreoptCache

发现获取不到什么有用的线索了,我们去源码里看一看,看看有什么新的结构或者方法供我们调用探索。

  • 源码探索

我们发现一些看起来有用的方法

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值