weak
关键字的作用弱引用,所引用对象的计数器不会加一,并在引用对象被释放的时候自动被设置为nil.
如何实现 weak
-
现在我们将
weak
的思路整理一下: -
整个系统中存在很多个对象,这些对象都可能会被弱引用,那么我们需要一个容器来容纳这些被弱引用的对象,比如数组,在此将这个容器的数据结构标识为
objectContainerDataStructure
; -
一个对象可能会被多次弱引用,当这个对象被销毁时,我们需要找到这个对象的所有弱引用,所以我们需要将这些弱引用的地址(即指针)放在一个容器里,比如数组,在此将这些弱引用的地址的数据结构标识为
pointerContainerDataStructure
; -
当对象不再被强引用时需要销毁的时候,我们需要通过这个对象在
objectContainerDataStructure
找到其对应的pointerContainerDataStructure
,进而找到这个对象的所有弱引用,将其置为nil
, -
通过上面的步骤,我们大概可以得出这么一个数据结构:
-
pointerContainerDataStructure
仅仅只是容纳一个对象的所有弱引用的地址,所以用数组即可; -
objectContainerDataStructure
是一个key-value
数据结构,将对象作为key
,对象的内存地址是最好的选择; -
在
iOS
中常用的key-value
数据结构就是字典Dictionary
,在这里我们的key
是一个数值对象,value
则是一个数值数组对象,可以用哈希表实现; -
总结
为了实现 weak
,我们需要这样的一张弱引用表:
-
表的数据结构是哈希表;
-
表的
key
是对象的内存地址; -
value
是指向该对象的所有弱引用的指针;
结尾
上面是如何自己实现weak
的一个大概思路,Apple
的实现可以看iOS底层解析weak的实现原理(包含weak对象的初始化,引用,释放的分析)一文。
【从历年weak看iOS面试】
2013年
面试官:代理用weak还是strong?
我 :weak 。
面试官:明天来上班吧
2014年
面试官:代理为什么用weak不用strong?
我 : 用strong会造成循环引用。
面试官:明天来上班吧
2015年
面试官:weak是怎么实现的?
我 :weak其实是 系统通过一个hash表来实现对象的弱引用
面试官:明天来上班吧
2016年
面试官:weak是怎么实现的?
我 :runtime维护了一个weak表,用于存储指向某个对象的所有weak指针。weak表其实是一个hash(哈希)表,key是所指对象的地址,Value是weak指针的地址(这个地址的值是所指对象指针的地址)数组。
面试官:明天来上班吧
2017年
面试官:weak是怎么实现的?
我 : 1 初始化时:runtime会调用objc_initWeak函数,初始化一个新的weak指针指向对象的地址。
2 添加引用时:objc_initWeak函数会调用 storeWeak() 函数, storeWeak() 的作用是更新指针指向,创建对应的弱引用表。
3 释放时,调用clearDeallocating函数。clearDeallocating函数首先根据对象地址获取所有weak指针地址的数组,然后遍历这个数组把其中的数据设为nil,最后把这个entry从weak表中删除,最后清理对象的记录。
面试官:明天来上班吧
2018年
面试官:weak是怎么实现的?
我 :跟2017年说的一样,还详细补充了objc_initWeak, storeWeak, clearDeallocating的实现细节。
面试官:小伙子基础不错。13k ,996干不干?干就明天来上班。。 下一个
2019年
面试官:weak是怎么实现的?
我 : 别说了,拿纸来,我动手实现一个。
面试官:等写完后,面试官慢悠悠的说,小伙子不错,我考虑考虑,你先回去吧