1

好的,所以我正在阅读 willSet/didSet 如何在 swift 中使用,我发现了一个关于 apples swift 文档的注释,这对我来说没有任何意义,我希望有人能解释一下。这是注释:

超类属性的 willSet 和 didSet 观察者在子类初始化器中设置属性时调用,在调用超类初始化器之后。在调用超类初始化程序之前,在类设置自己的属性时不会调用它们。

来自:https ://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/Properties.html

让我感到困惑的是,他们指出,在 B 对 A 的 super.init 调用之前,不会调用子类 B 中超类 A 属性的观察者。

class A {
    var p: Bool

    init() {
        p = false
    }
}

class B: A {

    override var p: Bool {
        didSet {
            print("didSet p")
        }
    }

    override init() {
        p = true // Compiler error
        super.init()
    }
}

然而,在那个时候,无论从 A 还是 B 都无法访问该属性,所以无论如何谁会打电话给观察者呢?尝试读/写该属性甚至会导致编译器错误,因此在 Swift 中甚至不可能错误地做到这一点。我是否遗漏了什么,或者这只是指出错误的误导性注释?

4

1 回答 1

2

他们正在谈论以下场景:

class A {
    var p: Bool {
        didSet {
            print(">>> didSet p to \(p)")
        }
    }

    init() {
        p = false // here didSet won't be called
    }
}

class B: A {

    override init() {
        // here you could set B's properties, but not those inherited, only after super.init()
        super.init()
        p = true // here didSet will be called
    }
}

B()

它将打印以下内容:

>>> didSet p to true

虽然对您来说这似乎很自然,但文档必须明确记录此行为。

于 2018-01-22T23:32:47.210 回答