26

当我覆盖该函数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"

那么我应该如何用观察者覆盖属性以及如何防止旧值也被执行?

4

3 回答 3

43

您可以覆盖属性的setandget部分并将您的移动到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,剩下的就是覆盖专门为此目的创建的辅助功能。

于 2015-04-08T00:29:41.280 回答
3

来自Swift 文档

超类属性的 willSet 和 didSet 观察者在子类初始化器中设置属性时调用,在调用超类初始化器之后。在调用超类初始化程序之前,在类设置自己的属性时不会调用它们。

于 2018-08-08T09:14:19.393 回答
0

子类中的观察者只添加到超类中定义的观察者。

来自官方文档:覆盖

覆盖属性

您可以覆盖继承的实例或类型属性以为该属性提供您自己的自定义 getter 和 setter,或者添加属性观察器以使覆盖的属性能够观察基础属性值何时更改。

于 2019-05-22T13:27:58.750 回答