03.SideTable和weak底层实现
我们先看一个小题目,看看下面的输出回事什么样的?
输出:
1、1、2。是不是很迷惑?别急我们慢慢来
前言
前面在对内存管理进行研究的时候接触到了 SideTalbe
,今天我们也依然会和他见面,它究竟是什么呢?
SideTable
可以看出, SideTable
是有多张的。它是一个 HashMap
。
一、 SideTable 的结构
简单了解了 SideTable 后我们继续回到题目。
二、 weak 做了什么
2.1 调试
在这里打上汇编断点
走到了 objc_initWeak
objc_initWeak
storeWeak
weak_register_no_lock
注册一个 对象 - weak指针 对。如果没有的话,创建一个 weak 的 entry 对象。
参数:
weak_table : SideTable 地址
referent : 被弱引用的对象
referrer : 弱引用指针地址
append_referrer
把 referrer 加进 entry 的 inline_referrers
这里又见到了熟悉的 3/4 扩容
weak_entry_t
三、 回到题目继续分析
我们在这里下个断点,并打开汇编断点:
来到了 objc_loadWeakRetained
objc_loadWeakRetained
内部继续跟进来到了 rootTryRetain
,这里内部引用计数会加
总结
weak
原理得到
SideTable
的弱引用表得到一个
weak_entry_t
把
referent
加入到entry
的数组inline_referrers
如果
weak_table
需要扩容3/4 扩容,类似与方法列表
把
new_entry
加入到weak_table
中
当我们使用一个
weakObjc
的时候,会调用rootTryRetain
,所以引用计数会 +1。也就是这里我们看到输出为 2 的原因所在。
Last updated