[英]When we should NOT use neither [weak self] nor [unowned self]?
我已经阅读了关于何时应该在闭包中使用[weak self]
或 [unowned self]
StackOverflow的几个讨论。
但是,是否有任何情况下,当我们没有用都没有 ,因为当我们只是明确使用斯威夫特不显示任何错误或警告self
封闭中。
例如,我们应该在这里使用weak
或unowned
?
UIView.animate(withDuration: 0.3) {
self.view.alpha = 0.0
}
如果闭合可能导致强参考周期,则需要使用[弱自我]或[无主自我]。
如果分配封闭自我的财产,你是指自己或关闭本身内部的自我属性可能发生这种情况。 闭包是引用类型,因此基本上相同的规则适用于强引用,就像使用普通类一样。
至于你的例子,不需要[weak self]
或[unowned self]
,因为你没有将闭包分配给self
引用的类中的变量,因此不会有强引用循环。
有关更多信息,请查看Swift编程语言指南中的“ 闭包的强引用循环”部分。 以下是上述链接中的一个示例:何时可以通过闭包引起强引用循环:
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")
}
}
如果在asHTML
的闭包中没有[unowned self]
,那么强大的引用循环将由分配给asHTML
的闭包引起。 将asHTML
的实现更改为以下内容可解决此问题:
lazy var asHTML: () -> String = {
[unowned self] in
if let text = self.text {
return "<\(self.name)>\(text)</\(self.name)>"
} else {
return "<\(self.name) />"
}
}
这有点基于意见,所以我会给出我的意见:)
我通常以同步性为基础。 如果闭包是Async,则调用close时调用实例可能不再存在,因此应该使用[weak self]
。 如果闭包是同步的,那就没必要了,捕获强引用也没关系。
这可以扩展为包括闭包,你可以合理地期望你的实例在被调用时保持有效(例如你的View动画案例),但要注意这假设闭包和你的使用将保持不变,所以它理论上可以在未来的某个时刻打破。 这种安全性降低,使未来的维护更加困难/危险。
对于像UIView.animate这样已建立且可预测的API,我个人倾向于使用强大的自我,但为了简洁起见,这是一个你需要自己做的评估,这取决于用法。
同样如评论中所述,功能关闭也是如此。 将闭包分配给另一个变量的属性有一组不同的问题。
顺便说一句,我采用了弱引用闭包的方法,简单地在我的Type中调用另一个方法,例如
thing.doSomethingWithAClosure() { [weak self]
self?.doSomething()
}
它简化了逻辑,同时还强制执行更多功能/模块化代码。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.