天天看点

OC对象之旅 weak弱引用实现分析

OC对象之旅 weak弱引用实现分析

根据调试信息,发现两者的区别是:

OC对象之旅 weak弱引用实现分析
OC对象之旅 weak弱引用实现分析
OC对象之旅 weak弱引用实现分析

所以重点就在 storeweak这个方法中,let's do it

storeweak源码的如下:

OC对象之旅 weak弱引用实现分析

ps:初始化isa那部分为何能阻止死锁,我没有看懂 该函数流程如下:

OC对象之旅 weak弱引用实现分析

重点来了:

sidetable

sidetable是一个结构体,定义如下

OC对象之旅 weak弱引用实现分析

taggedpointer

简单的说,这是一种优化手段,即将对象的值,存入对象的地址中,这些工程师简直丧心病狂,就为了省一点内存嘛!

进入正题,看看怎么实现弱引用的

先看看注册的过程吧

先从这行数的参数说起,参数有4个

OC对象之旅 weak弱引用实现分析

后三个参数不用解释,主要解释第一个参数,weak_table_t,定义如下

没错,weak_table_t就是寄存在sidetable中

OC对象之旅 weak弱引用实现分析

定义中我们重点关注weak_entry_t

weak_entry_t是最终存放对象和引用指针的地方,referent是被引用的对象,联合体union释义如下

OC对象之旅 weak弱引用实现分析

注册引用过程中,重点关注下面代码:

新建

通过weak_entry_t的源码,可以看到新建一个weak_entry_t的过程是

OC对象之旅 weak弱引用实现分析

调整weak_table_t的容量大小

当实际的数目大于old_size(old_size就是mask的大小+1),就去调整大小,同时重置max_hash_displacement为0,通过calloc函数,动态分配mask个的内存,然后通过循环,将原有的weak_entry_t插入到新的容器中,在插入的过程中,更新max_hash_displacement.

在weak_table_t插入weak_entry_t

过程比较简单,也是利用hash处理,方便后面查找。

在weak_table_t查找对象是通过循环遍历的方式,过程如下

在已有的weak_entry_t中加入引用

该过程同在weak_table_t中插入weak_entry_t如出一辙,要注意的是需要判断引用的个数,当引用个数大于weak_inline_count时,需要将原有的引用指针也移到referrers中,同时更新相关计数器。 上面过程的流程如下:

OC对象之旅 weak弱引用实现分析
OC对象之旅 weak弱引用实现分析

消除弱引用

消除弱引用过程同注册大致相同,只是部分地方是相反操作,不做赘述了

上一篇: Eth-Trunk

继续阅读