2015-04-07 199 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