mogelbuster
mogelbuster

Reputation: 1076

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?

Upvotes: 3

Views: 398

Answers (1)

DavidA
DavidA

Reputation: 3172

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)

Upvotes: 4

Related Questions