[英]MVVM: binding the View with the ViewModel with closures, unowned or weak self?
[英]Strong, weak and unowned self in closures explanation
我需要一些有关Swift闭包中引用的解释。 这是我的用例,让我们想象一下:
class A {...}
class B {
func makeAclosure() {
let instanceA = A()
instanceA.someFunctionA(completion: {(input) in
self.someAnotherFunction(input)
})
}
}
A级和B级之间是否存在保留周期? 在这种情况下,哪种情况可能是保留周期?
如果您的self
对象可能在调用闭包之前被释放,则应指定[weak self]
,以免发生错误的访问异常。
如果您知道绝对不会释放它,则可以使用[unowned self]
创建一个引用,该引用的行为类似于隐式解包的可选。
在您的示例中, B
的实例拥有对instanceA
的引用(在makeAClosure()
函数的上下文内),因此您不会以保留周期结束。
您应该考虑someFunctionA(completion:)
的实现,以确定在该闭包中是否需要对self
的unowned
或weak
引用。
(还有一点:如果您使用的是[weak self]
,则为了避免在整个代码中使用诸如self?
可选参数,您可以使用guard let `self` = self else { ... }
继续在代码中使用self
关闭代码。
如果不查看A.someFunctionA
,就无法说A.someFunctionA
因为不知道completion
是否在@escaping
(例如,是否保留)。 对于其余的答案,我将假定它为@escaping
。
Swift需要确保运行时的安全性,并通过强烈引用self
来保持将来可能需要的所有对象处于活动状态(因为self
是闭包内部唯一使用的变量)。
在这种情况下,没有参考周期 。 这是因为没有保留instanceA
,所以A => B,但是B!=>A。
但是,如果instanceA
被B
保留(假设您创建一个instanceA: A
属性并进行设置),那么您将拥有一个保留周期。
为了解决这个问题,您可以在闭包中使变量变weak
或不具有unowned
。 它们都做相同的事情,但是为您提供的类型略有不同。 它们都具有弱引用,这意味着instanceA
不会增加B
实例的引用计数; 如果B
被释放并且没有其他引用,则instanceA
也被释放。
当使用[weak self]
self
是optional
,例如self: B?
。 但是, [unowned self]
已显式展开,例如self: B!
。 这意味着,如果调用了闭包并且self
为nil
您的程序将崩溃。 这就是为什么在确定要释放B
也会释放A
时,仅使用unowned
的重要性。 在某些情况下, unowned
是安全的,例如创建闭包并将其存储在创建闭包的同一对象上的情况,但是对此存在更多细微差别。
如果不确定,请使用weak
!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.