一、前言
以往在使用Swift中的weak和unowned关键字的时候的理解是,两者都会解决循环引用的问题,weak更加适用于平行的两个生命周期,而unowned更加适用于一个包含另一个对象生命周期的生命周期(有点拗口,接下来会有一些解释)
二、weak与unowned背后
- weak:
weak引用表示不增加引用计数,并且当被引用的对象被释放时,将该weak引用自身设置为nil。
例如在使用delegate的时候,weak引用会非常有用,调用delegate方法的对象不应该持有这个delegate,所以delegate一般被标记为weak。
这就是所谓的平行的两个生命周期:A和B的生命周期是可以同时存在的,A被释放时候B可能还存在,B被释放时候同理,这时候他们之间的引用(为防止循环引用)更多是设置为weak。
weak引用可以为nil,所以它们必须是可选值类型,有时候我们并不想这么做,所以可以使用unowned。
- unowned:
unowned关键字表明不持有引用的对象,但是却假定该引用会一直有效。
对于每个unowned的引用,Swift在运行时将为这个对象维护另外一个引用计数,当所有的strong引用消失的时候,对象将把它的资源(比如对其他对象的引用)释放。不过,这个对象本身的内存将继续存在,直到所有的unowned引用也都消失。这部分内存将被标记为无效(有时候我们也把它叫做僵尸内存),当我们试图访问这样的unowned引用时,就会发生错误。
三、应用场合
- weak
一般使用在两个对象满足其生命周期没有太大关系之间。例如viewController和delegate等,它们的生命周期不是包含关系,而是互相平行的。
- unowned
一般使用在两个对象满足其中一个对象的生命周期包含另一个对象的生命周期。例如一个viewController中的timer的生命周期会被包含在viewController生命周期内,所以timer中的Block对self(viewController)的引用就使用unowned。
参考文献:《Swift进阶》 【德】Chris Eidhof Ole Begemann Airspeed Velocity 著 王巍 译
网友评论