带有 nil 值的 Swift 闭包捕获列表

标签 swift closures automatic-ref-counting block

我正在捕获一个委托(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/

相关文章:

python - 使用新的 Twilio 可编程语音 SDK 调用电话

swift - 将数据从 UIKit 传递到 SwiftUI(容器 UIHostingController)

ios - 防止键盘阻塞单元格

javascript - 如何重写 javascript 闭包函数调用

ios - ARC 使我痛苦

iphone - Receiver type() for instance message 是 ARC 中的前向声明问题

ios - 您需要 iOS 上的数据保护功能吗?

php - 在 PHP 中执行纯匿名函数

Groovy 闭包不捕获静态闭包变量

objective-c - 在我可以使用我的方法本地 NSOpenSavePanelDelegate 之前,ARC 会杀死它。有解决办法吗?