2017-08-09 178 views
1

我已经阅读了关于什么时候应该使用[weak self][unowned self]关闭的几个关于StackOverflow的讨论。什么时候我们不应该使用[weak self]和[unowned self]?

但是,有什么情况我们不需要使用既不是他们,因为当我们只是在闭包中明确使用self时,Swift不会显示任何错误或警告。

例如,我们应该在这里使用weak还是unowned

UIView.animate(withDuration: 0.3) { 
    self.view.alpha = 0.0 
} 
+1

在任何情况下,**没有提及**何时使用**的答案**? –

+1

另请参阅[强封闭循环参考](https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/AutomaticReferenceCounting.html#//apple_ref/doc/uid/TP40014097 -CH20-ID56)Swift编程语言指南的一部分。 –

回答

1

如果闭合会导致强参考周期,则需要使用[weak self]或[unowned self]。

此,如果你分配封盖的自我的属性,可能会发生,你指的自我盖子本身的属性。闭包是引用类型,因此基本上相同的规则适用于强引用,如同使用普通类一样。

至于你的例子,不需要[weak self][unowned self],因为你没有把闭包分配给self引用的类中的变量,所以不会有强的参考周期。

有关更多信息,请查阅Swift编程语言指南的Strong Reference Cycles for Closures部分。下面是从当强参考周期可以通过闭合而引起的所提到的链接的示例:

class HTMLElement { 

    let name: String 
    let text: String? 

    lazy var asHTML:() -> String = { 
     if let text = self.text { 
      return "<\(self.name)>\(text)</\(self.name)>" 
     } else { 
      return "<\(self.name) />" 
     } 
    } 

    init(name: String, text: String? = nil) { 
     self.name = name 
     self.text = text 
    } 

    deinit { 
     print("\(name) is being deinitialized") 
    } 

} 

没有[unowned self]asHTML封闭,强大的参考周期将通过分配给asHTML封闭引起的。将asHTML更改为以下解决方案可解决此问题:

lazy var asHTML:() -> String = { 
    [unowned self] in 
    if let text = self.text { 
     return "<\(self.name)>\(text)</\(self.name)>" 
    } else { 
     return "<\(self.name) />" 
    } 
} 
+0

等待,但这2个asHTML var实现有什么区别? – Legonaftik

+0

不小心将'[unowned self]'从正确的实现中排除,现在修复它。 –

1

这有点意见为主,所以我给我的意见:)

我一般将它基于同步。如果闭包是异步的,则在呼叫闭包机时呼叫实例可能不再存在,因此应使用[weak self]。如果一个闭包是同步的,这是不必要的,捕获一个强大的参考是好的。

可以扩大到包括关闭在那里你可以合理地预期,当它被称为(例如,您的观看动画时)的情况下仍然有效,但是请注意,这使得一个假设,即关闭和你对它的使用将保持不变,所以它在理论上可能在未来的某个时候突破。这不太安全,并使未来的维护更加困难/危险。

对于像UIView.animate这样既定且可预测的API,我个人倾向于为了简洁而使用强大的自我,但这是您需要自己做的评估,它取决于使用情况。

同样如注释中所述,函数闭包也是如此。将闭包分配给另一个变量的属性有一组不同的问题。另外,我已经采用弱引用闭包的方法,简单地调用我的类型中的另一种方法,例如,

thing.doSomethingWithAClosure() { [weak self] 
    self?.doSomething() 
} 

它简化了逻辑,同时执行更多的功能/模块化代码。

相关问题