我正在捕获一个委托引用,该引用最终设置为某个值,但最初为nil。但是,即使设置了委托,捕获的引用也将保持为零。
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
}
这是怎么回事?
答案 0 :(得分:1)
使用[weak delegate] in
之类的列表,将在初始化关闭的那一刻复制代表的值。因此,当委托在那一刻是nil
时,如果将nil
留在闭包中,则不管以后是否修改self.delegate
。 [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()
这里,closure()
中的最后一个func bar
调用将打印nil
,因为delegate
当时是nil
初始化。