「OC」源码学习——cache_t的原理探究
前言
上一次我们讲到了objc_class的isa和bits之中的内容,接下来就是cache_t之中的内容。
cache_t探究
前面我们提到在类对象之中isa和superclass各占8个字节,所以我们可以直接通过内存平移获取相关内容,于是我们打开lldb继续调试

好吧,看起来好像一点有用的看不到,没关系,我们接着查找到cache_t的定义

可以看到在当前架构下,有用的属性为 _bucketsAndMaybeMask,_unused,_flags,_occupied,_originalPreoptCache,但由于_originalPreoptCache和_unused,_flags,_occupied组成的结构体组成了联合体,由于联合体的互斥特性,我们可以先不看_originalPreoptCache,_unused是占位符可以实现八位对齐

通过源码的学习,我们可以知道这时候其实可以通过cache提供给的buckets()方法去获取_buckets,就可以获取sel-imp了,这两个的获取在bucket_t结构体中同样提供了相应的获取方法sel() 以及 imp(pClass),我们可以通过内存偏移的方法去获取第二个


总结出cache_t的结构如上图
insert函数

在运行完-[GGObject speak]方法之后,_occupied进行了自增,而调用-[GGObject sayHello]之后在查看发现_occupied又变成了1,这是为什么呢?
我们来看看cache_t之中关于insert的函数,就是将函数缓存插入bucket_t之中的实现
void cache_t::insert(SEL sel, IMP imp, id receiver)
{
lockdebug::assert_locked(&runtimeLock);
// Never cache before +initialize is done
if (slowpath(!cls()->isInitialized())) {
return;
}
if (isConstantOptimizedCache()) {
_objc_fatal("cache_t::insert() called with a preoptimized cache for %s",
cls()->nameForLogging());
}
#if DEBUG_TASK_THREADS

最低0.47元/天 解锁文章
2420

被折叠的 条评论
为什么被折叠?



