当我覆盖函数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"
那么我应该如何用观察者覆盖属性以及如何防止旧值被执行呢?
答案 0 :(得分:32)
您可以覆盖属性的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
,剩下的就是覆盖特别为此目的而创建的辅助功能。
答案 1 :(得分:0)
在调用超类初始化器之后,在子类初始化器中设置属性时,将调用超类属性的willSet和didSet观察器。在调用超类初始化程序之前,类在设置其自己的属性时不会调用它们。
答案 2 :(得分:0)
子类中的观察者仅添加到超类中定义的一个。
摘自官方文档:Overriding
覆盖属性
您可以覆盖继承的实例或类型 属性,以提供您自己的自定义获取和设置器 属性,或添加属性观察者以启用覆盖 属性,以便在基础属性值更改时进行观察。