Override property observer

拈花ヽ惹草 提交于 2019-11-29 11:08:55

问题


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?


回答1:


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.




回答2:


From the Swift documentation

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.




回答3:


Observers in subclasses are only added to the one defined in the superclass.

From official documentation: Overriding

Overriding Properties

You can override an inherited instance or type property to provide your own custom getter and setter for that property, or to add property observers to enable the overriding property to observe when the underlying property value changes.



来源:https://stackoverflow.com/questions/29503482/override-property-observer

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!