Переопределить наблюдателя свойств

Когда я переопределяю функцию noise, функция заменяется на новую. Но когда я переопределяю свойство с наблюдателем, старое и новое значение получают оба исполнения.

В детской площадке:

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)")
    }
}

Вывод:

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

Но когда я делаю то же самое с свойством с наблюдателем:

В детской площадке:

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

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

Вывод:

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

Итак, как я могу переопределить свойство с наблюдателем и как предотвратить выполнение старых значений?

Ответы

Ответ 1

Вы можете переопределить часть свойства set и get и переместить туда println. Таким образом, Swift не будет вызывать исходный код - если вы не вызываете 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")
        }
    }
}

Это не очень, но.

Здесь лучшее и простое решение:

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

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

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

Поскольку невозможно "переопределить" didSet, то остается переопределение вторичной функции, специально созданной для этой цели.

Ответ 2

Из документации Swift

WillSet и didSet наблюдатели свойств суперкласса вызываются, когда свойство устанавливается в инициализаторе подкласса после вызова инициализатора суперкласса. Они не вызываются, пока класс устанавливает свои собственные свойства до вызова инициализатора суперкласса.

Ответ 3

Наблюдатели в подклассах добавляются только к тому, который определен в суперклассе.

Из официальной документации: переопределение

Переопределение свойств

Вы можете переопределить унаследованное свойство экземпляра или типа, чтобы предоставить свой собственный метод получения и установки для этого свойства, или добавить наблюдатели свойства, чтобы свойство переопределения могло наблюдать, когда изменяется значение базового свойства.