【从历年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是怎么实现的? 我 : 别说了,拿纸来,我动手实现一个。 面试官:等写完后,面试官慢悠悠的说,小伙子不错,我考虑考虑,你先回去吧
@onevcat:可以加一问 Swift 的 weak 和 ObjC 的 weak 实现有何异同什么的 [笑cry]
2020年: 我觉得苹果的实现不好,这是我的优化方案…
iOS 底层解析weak的实现原理(包含weak对象的初始化,引用,释放的分析)https://www.jianshu.com/p/13c4fb1cedea
实现主要在 objc-weak.h、objc-weak.mm 和 NSObject.mm 这三个文件中。
- 初始化时:runtime会调用objc_initWeak函数,初始化一个新的weak指针指向对象的地址。
当我们像下面那样初始化一个弱引用时:
// NSObject *o = ...;
__weak id weakPtr = o;
/////编译器会转换为下面的实现:
// NSObject *o = ...;
objc_initWeak(&weakPtr, o);
-
添加引用时:objc_initWeak函数会调用 storeWeak() 函数, storeWeak() 的作用是更新指针指向,创建对应的弱引用表。
-
释放时,调用clearDeallocating函数。clearDeallocating函数首先根据对象地址获取所有weak指针地址的数组,然后遍历这个数组把其中的数据设为nil,最后把这个entry从weak表中删除,最后清理对象的记录。
swift中的unowned
unowned使用在Swift中,也会分 weak 和 unowned。unowned 的含义跟 __unsafe_unretained 差不多。假如很明确的知道对象的生命期,也可以选择 unowned。
Swift 的 weak 和 ObjC 的 weak 实现有何异同 https://juejin.im/entry/5a5f2f646fb9a01c9950d7f4
swift4之前
在 Swift 里苹果把弱引用的实现简化了,弱引用变量只保存指向目标对象的地址,并通过对象內的弱引用计数进行内存管理。 Swift 把对象的析构和释放时机进行了解耦,析构发生在强引用数为零时,只有强弱引用数都为零才会释放。 使用弱引用时,runtime 会检查目标对象的状态,如果已经析构了就会执行 zeroing 操作。
swift4之后
苹果再次加入 SideTable 的机制。
不过此 SideTable 跟 OC 的 SideTable 不一样,系统不再是把它作为全局对象使用。新的 SideTable 是针对有需要的对象而创建,系统会为目标对象分配一块新的内存来保存该对象额外的信息。