繁体   English   中英

封闭说明中的强,弱和无主自我

[英]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:)的实现,以确定在该闭包中是否需要对selfunownedweak引用。


(还有一点:如果您使用的是[weak self] ,则为了避免在整个代码中使用诸如self?可选参数,您可以使用guard let `self` = self else { ... }继续在代码中使用self关闭代码。

如果不查看A.someFunctionA ,就无法说A.someFunctionA因为不知道completion是否在@escaping (例如,是否保留)。 对于其余的答案,我将假定它为@escaping

Swift需要确保运行时的安全性,并通过强烈引用self来保持将来可能需要的所有对象处于活动状态(因为self是闭包内部唯一使用的变量)。

在这种情况下,没有参考周期 这是因为没有保留instanceA ,所以A => B,但是B!=>A。

但是,如果instanceAB保留(假设您创建一个instanceA: A属性并进行设置),那么您将拥有一个保留周期。

为了解决这个问题,您可以在闭包中使变量变weak或不具有unowned 它们都做相同的事情,但是为您提供的类型略有不同。 它们都具有弱引用,这意味着instanceA不会增加B实例的引用计数; 如果B被释放并且没有其他引用,则instanceA也被释放。

当使用[weak self] selfoptional ,例如self: B? 但是, [unowned self]已显式展开,例如self: B! 这意味着,如果调用了闭包并且selfnil您的程序将崩溃。 这就是为什么在确定要释放B也会释放A时,仅使用unowned的重要性。 在某些情况下, unowned是安全的,例如创建闭包并将其存储在创建闭包的同一对象上的情况,但是对此存在更多细微差别。

如果不确定,请使用weak

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM