Swift 覆盖属性观察者
当我重写函数Swift 覆盖属性观察者,swift,properties,overriding,didset,Swift,Properties,Overriding,Didset,当我重写函数noise时,该函数将被新函数替换。但是当我用一个观察者重写一个属性时,新旧值都会被执行 在游乐场: class Vehicle { func noise(sound: String) { println("Vehicle sound sounds like \(sound)") } } class Train: Vehicle { override func noise(sound: String) { println("A
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)")
}
}
class Foo {
var something: Int! {
didSet {
println("vroom")
}
}
}
class Bar: Foo {
override var something: Int! {
didSet {
println("toot toot")
}
}
}
输出:
var oldTrain = Train()
bulletTrain.noise("tjoek tjoek") // Prints: "A train does: tjoek tjoek"
var foobar = Bar()
foobar.something = 3 // Prints: "vroom" & "toot toot"
但当我对一个观察者的财产做同样的事情时:
在游乐场:
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)")
}
}
class Foo {
var something: Int! {
didSet {
println("vroom")
}
}
}
class Bar: Foo {
override var something: Int! {
didSet {
println("toot toot")
}
}
}
输出:
var oldTrain = Train()
bulletTrain.noise("tjoek tjoek") // Prints: "A train does: tjoek tjoek"
var foobar = Bar()
foobar.something = 3 // Prints: "vroom" & "toot toot"
那么,我应该如何使用观察者覆盖属性,以及如何防止旧值也被执行?您可以覆盖属性的
集
和获取
部分,并将println
移动到那里。这样,斯威夫特就不会调用原始代码——除非您调用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,剩下的就是覆盖专门为此目的创建的辅助函数。来自
调用超类初始值设定项后,在子类初始值设定项中设置属性时,将调用超类属性的willSet和didSet观察器。在调用超类初始值设定项之前,在类设置自己的属性时不会调用它们
子类中的观察者仅添加到超类中定义的观察者 从正式文件: 覆盖属性 您可以重写继承的实例或类型 属性提供您自己的自定义getter和setter 属性,或添加属性观察者以启用覆盖 当基础属性值更改时要观察的属性
似乎无法阻止旧的属性观察器被执行。令人惊讶的是,您无法覆盖@nhgrif建议的
didSet
,我将这两个解决方案组合成了一个答案。谢谢,这帮了大忙。奇怪的是,你不能直接覆盖didSet
。正如我所读到的,苹果不久前修复了一些与didSet相关的bug。我感觉他们仍然有很多关于didSet的bug需要修复。我认为在任何时候都不可能允许覆盖属性观察器。。。