【问题标题】:Swift closure capture list with nil values具有 nil 值的 Swift 闭包捕获列表
【发布时间】:2019-03-22 22:39:40
【问题描述】:

我正在捕获最终设置为某个值但最初为零的委托引用。但是,即使设置了委托,捕获的引用仍然为零。

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
}

这是怎么回事?

【问题讨论】:

  • 我不明白为什么每个人都反对这个问题。没有错。
  • 嗯,是的,真的,奇怪..我希望有一个字段,人们必须输入拒绝投票的原因。

标签: swift closures automatic-ref-counting block


【解决方案1】:

使用像[weak delegate] in 这样的捕获列表将在初始化闭包的那一刻复制委托的值。因此,当代理在那一刻为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,因为在初始化 closure 时,delegatenil

【讨论】:

  • 谢谢先生。是的,但是我有点期待在闭包初始化时复制的内容是指向某种可选结构的指针,并且如果可选变为非零,则指针将反映这一点。但看起来在运行时什么都没有,要么有一个指向委托的指针,要么有一个 0x0 或该指针中指示 nil 的任何值。正如你所说,它是复制的。感谢您花时间编写示例!
  • 您只需跳过捕获列表,一切都会正常。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-12
  • 1970-01-01
  • 1970-01-01
  • 2018-08-14
相关资源
最近更新 更多