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。


种一棵树最好的时间是在十年前,而后是现在。

Loading Disqus comments...
Table of Contents