我正在捕获一个委托(delegate)引用,该引用最终设置为某个值,但最初为零。但是,即使设置了委托(delegate),捕获的引用仍为零。
DispatchQueue.main.asyncAfter(deadline: .now() + .seconds(2)) { [weak delegate] in
delegate?.something() // delegate is nil
}
DispatchQueue.main.asyncAfter(deadline: .now() + .seconds(2)) { [weak self] in
self?.delegate?.something() // delegate is not nil
}
这是怎么回事?
最佳答案
在中使用像[weak delegate]这样的捕获列表将在闭包初始化时复制委托(delegate)的值。因此,当委托(delegate)在那一刻为
nil
时,无论您是否修改 self.delegate
, if 都会在闭包内保留 nil
稍后的时间。这也适用于 [weak self]
,除了 self
在 Swift 中通常不会改变。
检查这个例子:
class Delegate {
}
class A {
var delegate:Delegate?
func foo() {
print ("in foo ---------------------")
delegate = nil
print ("delegate before: \(delegate)") // prints: "nil"
var closure = { print ("in closure: \(self.delegate)")}
closure() // prints: "in closure: nil"
delegate = Delegate()
print ("delegate after: \(delegate)") // prints "Optional(SwiftPlayground.Delegate)"
closure() // prints "in closure: Optional(SwiftPlayground.Delegate)"
}
func bar() {
print ("in bar ---------------------")
delegate = nil // prints "nil"
print ("delegate before: \(delegate)")
var closure = { [weak delegate] in print ("in closure: \(delegate)")}
closure() // prints: "in closure: nil"
delegate = Delegate() // prints "Optional(SwiftPlayground.Delegate)"
print ("delegate after: \(delegate)")
closure() // prints "nil"
}
}
let a = A()
a.foo()
a.bar()
这里,func bar
中的最后一个 closure()
调用将打印 nil
,因为 delegate
是闭包
初始化时nil
。
关于带有 nil 值的 Swift 闭包捕获列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52868622/