Swift中的weak与unowned
本篇是研读Chris Eidhof, Ole Begemann, Airspeed Velocity著的《Swift 进阶》(对应Swift 5.6)所做下的笔记,可能掺杂了些许本人浅薄的思考,如有纰漏,恳请赐教。
网络上大多数关于weak与unowned的解释比较简单粗暴,即变量不会变为nil时使用unowned,反之则使用weak。上次面试时我这么回答了,答完之后顿觉不妥,这似乎根本算不上一个解释。
弱引用(weak)
弱引用不会改变实例的引用计数,引用计数归零时,变量会被置为nil。
而这个特性导致了swift中的弱引用变量必须是一个可选型
无主引用(unowned)
无主引用同样不会改变实例的引用计数,但并不要求变量是可选型
内存管理上的差异
-
weak引用的实例引用计数降为0时,实例会被销毁,内存会被释放掉,访问被释放的实例会得到nil。
-
unowned引用的实例,即使引用计数为0,占用的内存也不会被回收,而是被打上了无效的标记,被称为僵尸内存(zombie memory),这时尝试访问这个实例会发生一个运行时错误(Fatal error: Attempted to read an unowned reference but object 0x60000330c0a0 was already deallocated)
unowned的缺点
- 如果误判了对象的生命周期,程序会崩溃
unowned的优点
- unowned可以被声明为let
- unowned更方便,不需要是可选型。
- unowned的访问效率会高一点,但应该只在对效率非常敏感的代码中才考虑这一点
典型场景
当两个对象之间是父子关系时。当父对象使用强引用来控制其子对象的生命周期,并且我们可以保证没有其他对象知道子对象存在的话,子对象对父对象的引用就可以是 unowned。