Search code examples
swiftobserversdidset

Swift variable observers not called before super.init called


Okay so I was reading up on how willSet/didSet are used in swift and I came across a note on apples swift docs that just doesn't make any sense to me and I hope someone can explain. Here's the note:

The willSet and didSet observers of superclass properties are called when a property is set in a subclass initializer, after the superclass initializer has been called. They are not called while a class is setting its own properties, before the superclass initializer has been called.

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

What confuses me is that they point out that the observers on superclass A properties in a subclass B aren't called before the super.init call by B to 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()
    }
}

However the property is never even accessible in that time from either A nor B, so who's gonna call the observers anyway? Attempting to read/write the property will even result in a compiler error so it's never even possible to do it by mistake in Swift. Am I missing something or is this just a misleading note that points out the wrong thing?


Solution

  • They are talking about following scenario:

    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()
    

    It will print following:

    >>> didSet p to true
    

    While to you it might seems natural, the documentation has to explicitly document this behavior.