繁体   English   中英

当我们不应该既不使用[弱自我]也不使用[无主自我]?

[英]When we should NOT use neither [weak self] nor [unowned self]?

我已经阅读了关于何时应该在闭包中使用[weak self] [unowned self] StackOverflow的几个讨论。

但是,是否有任何情况下,当我们没有用都没有 ,因为当我们只是明确使用斯威夫特不显示任何错误或警告self封闭中。

例如,我们应该在这里使用weakunowned

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.

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