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
发现获取不到什么有用的线索了,我们去源码里看一看,看看有什么新的结构或者方法供我们调用探索。
- 源码探索
我们发现一些看起来有用的方法