SideTable 之上是个SideTables,里面存储着SideTable
具体有关SideTables请看runtime(二) SideTables
这个表是由runtime来进行维护的,
其实是站在局外来对创建的对象进行统一的管理(并不是在对象本身内部对自己的引用计数和weak引用进行管理的(引用计数在超出对象isa引用计数存储上限的情况下,没有超出的话,对象本身是可以管理自己的引用计数的)),我之前的认识是对象本身会管理自己的引用计数以及弱引用表
SideTable 存储有两个重要的结构
1. refcnts
2. weak_table
refcnts 中就保存了对象的引用计数(这里是超出了对象isa中引用计数最大值的对象),
refcnts 中有个数组,元素就是(对象地址,引用计数)类似swift中元组,
所以每一个SideTable中是存储了多个对象的引用计数的
引用计数变化的流程是:
1.通过对象地址,找到对应的 SideTable;
2.通过对象地址找到(对象地址,引用计数);
3.对引用计数+1,-1操作
weak_table 中是保存对象的weak引用
weak_table 中也有个数组,元素是个(对象地址,弱引用此对象的指针数组)weak_entry_t,
其中这个弱引用数组每一个元素就是弱指针地址
所以当对象销毁的时候,weak变为nil的流程是
1.通过对象地址,找到对应的 SideTable;
2.继续通过对象地址,找到 weak_table 中对应的weak_entry_t;
3.遍历弱引用表,将其中的弱引用指针变为nil;
4.将weak_entry_t从数组中移除
通过上述,我知道了,引用计数和weak引用是分别存储的,我之前一直认为他们是这样的结构:{对象地址:{引用计数:10,weakList:[0x1,0x2]}}
,其实他们是{对象地址:{引用计数:10}}
,{对象地址:{weakList:[0x1,0x2]}}
,关于为什么不用上边的结构,我就不太知道了,主要是通过上边的文章更新了自己的认识
网友评论