Override property observer

Eendje picture Eendje · Apr 8, 2015 · Viewed 13k times · Source

When I override the function noise, the function gets replaced by the new one. But when I override a property with an observer, the old and new value gets both executed.

In playground:

class Vehicle {
    func noise(sound: String) {
        println("Vehicle sound sounds like \(sound)")
    }
}

class Train: Vehicle {
    override func noise(sound: String) {
        println("A train does: \(sound)")
    }
}

Output:

var oldTrain = Train()
bulletTrain.noise("tjoek tjoek") // Prints: "A train does: tjoek tjoek"

But when I do the same with an property with an observer:

In playground:

class Foo {
    var something: Int! {
        didSet {
            println("vroom")
        }
    }
}

class Bar: Foo {
    override var something: Int! {
        didSet {
            println("toot toot")
        }
    }
}

Output:

var foobar = Bar()
foobar.something = 3 // Prints: "vroom" & "toot toot"

So how am I supposed to override a property with an observer and how to prevent the old values to be executed as well?

Answer

Jean Le Moignan picture Jean Le Moignan · Apr 8, 2015

You can override the set and get part of the property and move your println there. This way Swift won't call the original code -- unless you call super.

class Foo {
    private var _something: Int!

    var something: Int! {
        get {
            return _something
        }
        set {
            _something = newValue
            println("vroom")
        }
    }
}

class Bar: Foo {
    override var something: Int! {
        get {
            return _something
        }
        set {
            _something = newValue
            println("toot toot")
        }
    }
}

That's not pretty, though.

Here's a better -- and simpler -- solution:

class Foo {
    var something: Int! {
        didSet {
            somethingWasSet()
        }
    }

    func somethingWasSet() {
        println("vroom")
    }
}

class Bar: Foo {
    override func somethingWasSet() {
        println("toot toot")
    }
}

Since there is no way to "override" the didSet, what remains is overriding a secondary function especially created for that purpose.