2015-04-07 128 views
14

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

似乎没有办法阻止旧的属性观察者被执行。 – mrahmiao

+0

它是惊人的,你不能重写'didSet' – Fattie

回答

24

您可以覆盖该属性的setget部分并将您的println移动到那里。这样Swift不会调用原始代码 - 除非你叫超级。

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,剩下的就是重写为此目的而创建的辅助功能。

+0

正如@nhgrif所建议的那样,我将这两个解决方案组合成一个答案。 –

+0

谢谢,这帮了一大堆。奇怪你不能只是重写'didSet'。正如我读过的,苹果在很久以前就修复了一些与'didSet'有关的bug。我觉得他们仍然有许多bug来解决'didSet'的问题。 – Eendje

+0

我不认为允许财产观察员被重写很可能在任何时候在作品中...... – nhgrif