iOS底层-类的探索分析之cache
2021-06-24 本文已影响0人
似水流年_9ebe
前言
前面两篇文章我们介绍了isa,继承链(iOS底层-类的探索分析之isa及继承链),类的属性和成员变量的存储,对象方法以及类方法的存储(iOS底层-类的探索分析之类的属性及类的方法),现在我们再来探索下cache
cache数据结构
我们先断点,利用lldb调试,如图所示:
1
接着,我们在lldb环境中执行以下命令,如图:
2
然后,我们再把cache_t结构体的成员截图上传:
3
从上两幅图中可以看出,我们在lldb打印的数据正好跟cache_t结构体的成员对应上,经过一系列的源码查找和分析,我们可以得出cache_t的数据结构:
4
cache的方法存储
我们接着再验证一下,我们通过lldb的调试去验证方法的存储,如图所示:
5 6我们通过lld命令找到了方法在cache_t中存储在buckets(它存储的是bucket_t结构体,采用的是哈希函数的存储方式,结合了数组和链表的特性)中。
cache底层原理分析
方法的存储必然会有写入和读取的操作,我们通过源码可以看找到一个方法,如图:
我们接着分析这个insert方法。
8
进入这个方法,会判断如果是第一次进来,也就是没有缓存的情况,调用reallocate方法,在这个方法内部会调用setBucketsAndMask方法,创建一个bucket存储。
之后,会调用这以下代码:
9
- 计算开始查找位置
- 判断如果sel是否存在,如果不存在,在合适位置插入进去
- 如果存在,不处理
如果cache已经有数据,会调用以下代码:
10
newOccupied + CACHE_END_MARKER <= cache_fill_ratio(capacity))这个条件成立不处理,其中cache_fill_ratio超过3/4就扩容。
超过这个3/4就会调用以下代码:
11
就会进行两倍扩容,如果超过最大值,就使用最大值(MAX_CACHE_SIZE为7),然后调用reallocate方法,创建bucket,接着执行上面的插入流程。
在reallocate会调用 collect_free方法进行清空旧的数据,内存的扩容的时候,其实是得新copy一份,会很占用内存,新调用的方法会被存储起来。
结语
这个是个人对类中的cache的基本分析,很多不完善的地方,希望可以指正。