【发布时间】:2018-10-26 15:30:21
【问题描述】:
我为此使用的标题可能不是特别清楚,所以我希望一个工作代码示例可以提供一些清晰。
我面临的问题是我有一个类似于下面代码的场景:
import Foundation
class Test {
private var isInner = false {
didSet {
print("isInner: \(isInner)")
}
}
private func runClosure(closure: () -> ()) {
closure()
}
func callClosure() {
// Weak 1
runClosure { [weak self] in
self?.isInner = false
guard let strongSelf = self else { return }
// Can this [weak self] create problems?
// Weak 2
strongSelf.runClosure { [weak self] in
self?.isInner = true
}
}
}
}
let test = Test()
test.callClosure()
// The following is printed to the console
// isInner: false
// isInner: true
上面的一切都按预期工作,这很好。
我担心的是[weak self] 的第二次使用。虽然self 在函数开始时被声明为weak (Weak1),但不久之后我将其设置为strongSelf。
我可以重新使用我之前的 strongSelf,但有问题的函数实际上可能是长时间运行的操作,并且存在 self 可能超出 Weak1 和 之间的范围的可能性弱2。
但是,我注意到Weak2 存在无效的可能性,这是我希望通过这个问题澄清的。
最终,weak 所做的只是为 self 创建一个可选变量,所以我不知道任何潜在的陷阱。另外,Weakself1、strongSelf和Weakself2在callClosure()的执行过程中都指向同一个内存地址。
【问题讨论】:
-
在您的示例中,weak - strong 舞蹈毫无意义,因为关闭不会导致保留周期。
-
谢谢@vadian,这是我的想法之一。我对第二个弱者的初衷只是非常谨慎,但如果没有意义,我很乐意放弃它。
-
您的示例中的所有内容都是同步运行的,因此不需要
weak/strong,因为无论如何该对象都没有机会释放。 -
是的,但我不想将专有生产代码复制到我的问题中。我确实更进一步提到了真正的操作可能会长期运行。
-
您到底关心什么?假设
runClosure在你的真实代码中异步完成,当外部闭包完成时,strongSelf持有的强引用将被释放。有可能在调用第二个闭包时,如果self到那时已被释放,则第二个weak self将是nil,但是您可以使用可选的 unwrap 检查这一点。它不能是“无效的”。它要么引用self,要么引用nil
标签: ios swift closures weak-references