具有零值的Swift闭包捕获列表
我捕获的委托引用最终设置为某个值,但最初为零。但是,即使已设置委托,捕获的引用仍保持为零具有零值的Swift闭包捕获列表,swift,closures,automatic-ref-counting,block,Swift,Closures,Automatic Ref Counting,Block,我捕获的委托引用最终设置为某个值,但最初为零。但是,即使已设置委托,捕获的引用仍保持为零 DispatchQueue.main.asyncAfter(deadline: .now() + .seconds(2)) { [weak delegate] in delegate?.something() // delegate is nil } DispatchQueue.main.asyncAfter(deadline: .now() + .seconds(2)) { [weak self
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]之类的caputure列表将复制委托的值。因此,当委托在那一瞬间为nil时,if将在闭包内保持为nil,无论您稍后是否修改self.delegate。这也适用于[弱自我],只有一点例外,自我通常不会在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中的最后一个闭包调用将打印nil,因为在初始化闭包时委托是nil。我不明白为什么每个人都对这个问题投了否决票。没什么不对的嗯是的真的很奇怪。。我希望有一个领域,人们必须输入否决投票的理由。谢谢主席先生。是的,但是我有点期待在闭包初始化时复制的是指向某种可选结构的指针,如果可选结构变为非nil,指针将反映这一点。但看起来在运行时什么都没有,要么是一个指向委托的指针,要么是一个0x0,或者是指针中指示nil的任何值。照你说的复制。感谢您抽出时间编写示例!您只需跳过捕获列表,一切都会正常工作。