mogelbuster mogelbuster - 1 month ago 6
Swift Question

Mixing Swift Property Observers and Inheritance

I've been tinkering with this, and I was wondering if there is any literature on this subject, or any way of knowing what is the expected behavior. Here is an example:

class A {
var paused:Bool = false {
willSet { print("Class A willSet on paused called") }
didSet { print("Class A didSet on paused called") }
}
}

class B : A {
override var paused:Bool {
willSet { print("Class B willSet on paused called") }
didSet { print("Class B didSet on paused called") }
}
}

class C : B {
override var paused:Bool {
willSet { print("Class C willSet on paused called") }
didSet { print("Class C didSet on paused called") }
}
}

let testC = C()
testC.paused = true


When this runs I get this output:

Class C willSet on paused called
Class B willSet on paused called
Class A willSet on paused called
Class A didSet on paused called
Class B didSet on paused called
Class C didSet on paused called


It seems that the
willSet
is called in the usual manner of polymorphism, but
didSet
is called backwards. This is kind of cool, but where is this behavior documented? Is a test like this the only way of learning it?

Answer

The order of the didSet calls is as expected - each child calls it's willSet, then calls super, then calls it's didSet. If you did it with literal calls to super.pause you'd have something like this, which makes the order of the didSet calls clear:

class A {
    var paused:Bool = false

    func pause(_ paused:Bool) {
        print("Class A will set paused")
        self.paused=paused
        print("Class A did set paused")
    }
}

class B : A {
    override func pause(_ paused:Bool) {
        print("Class B will set paused")
        super.pause(paused)
        print("Class B did set paused")
    }
}

class C : B {
    override func pause(_ paused:Bool) {
        print("Class C will set paused")
        super.pause(paused)
        print("Class C did set paused")
    }
}

let testC = C()
testC.pause(true)