Swift
使用的自动引用技术ARC
(Automatic Reference Count
)这一机制来跟踪和管理程序的内存使用状况。Swift
的ARC
机制只是对于基于引用计数的对象采有效,对于基于值拷贝的,比如struct
、enum
是无效的。Swift
提供了两种方法解决循环强引用问题:弱引用(weak reference)
和无主引用(unowned reference
)。- 对于生命周期内会变为
nil
的实例使用弱引用。相反的,对于初始化赋值后再也不会被赋值为nil
的,使用无主引用。 - 弱引用(
weak
)
- 弱引用必须声明为变量,表明其值在运行时可以被修改。
- 弱引用不能被声明为常量。
- 因为弱引用可以没有值,所以必须将每一个弱引用声明为可选类型。
无主引用(
unowned
)- 无主引用是永远有值的。
- 无主引用总是被定义为非可选类型。
- 可以在声明属性或者变量时,在前面加上关键字
unowned
,表示这是一个无主引用。 - 如果试图在实例被销毁后访问该实例的无主引用,会触发运行时错误。使用无主运用,必须确保无主引用始终指向一个未销毁的实例。
- 如果试图访问实例已经被销毁的无主引用,程序会直接崩溃。而不会发生无法预期的行为。因此,应避免这样的事情发生。
两个类的属性值都允许为
nil
,并且会潜在产生循环强引用,适用于weak
。- 两个类的其中一个属性值允许为
nil
,而另外一个属性的值不允许为nil
,并且会潜在产生循环强引用,适用于unowned
。 - 如果两个属性值都必须有值,并且初始化之后不能为
nil
,在此种情况下,一个属性值需要使用unowned
修饰,另外一个属性值不能为nil
。这时候需要一个属性值用unowned
修饰,另一个属性值使用显示展开的可选属性。
- 闭包引起的循环强引用
- 在定义闭包的同时,定义占有列表作为闭包的一部分,用以解决闭包的循环强引用。
- 占有列表的每个元素都是由
weak
和unowned
关键字和实例的引用成对组成。每一对都在花括号中,通过逗号隔开。 - 占有列表放置在闭包参数列表和返回类型之前,代码示例:
class Clourse{
lazy var someClourse:(Int,String) -> String = {
[unowned self] (index:Int,stringToProcess:String) ->String in
// 闭包代码
return "wangsk"
}
}
- 如果闭包没有指定参数列表或者返回类型,则可以通过上下文盘算,可以将占有列表放在闭包开始的地方,跟着使用关键字:
in
。代码示例:
class Clourse2{
lazy var someClourse2:() -> String = {
[unowned self] in
// 闭包代码
return "wangsk2"
}
}