2015-04-07 22 views
14

Gdy zastąpię funkcję noise, funkcja zostanie zastąpiona przez nową. Ale kiedy przesłonię nieruchomość obserwatorem, stara i nowa wartość zostaną wykonane.Zastępowanie obserwatora właściwości

W Playground:

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)") 
    } 
} 

wyjściowa:

var oldTrain = Train() 
bulletTrain.noise("tjoek tjoek") // Prints: "A train does: tjoek tjoek" 

Ale kiedy zrobić to samo z własności z obserwatorem:

W Playground:

class Foo { 
    var something: Int! { 
     didSet { 
      println("vroom") 
     } 
    } 
} 

class Bar: Foo { 
    override var something: Int! { 
     didSet { 
      println("toot toot") 
     } 
    } 
} 

Wyjście:

var foobar = Bar() 
foobar.something = 3 // Prints: "vroom" & "toot toot" 

W jaki więc sposób mam zastąpić nieruchomość z obserwatorem i jak zapobiec również starszym wartościom?

+0

Wygląda na to, że nie można uniemożliwić uruchomienia starego obserwatora własności. – mrahmiao

+0

To niesamowite, że nie można przesłonić 'didSet' – Fattie

Odpowiedz

24

Możesz zastąpić część nieruchomości i przenieść tam println. W ten sposób Swift nie wywoła oryginalnego kodu - chyba że zadzwonisz 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") 
     } 
    } 
} 

To jednak nie jest ładne.

Oto lepsze - i prostsze - rozwiązanie:

class Foo { 
    var something: Int! { 
     didSet { 
      somethingWasSet() 
     } 
    } 

    func somethingWasSet() { 
     println("vroom") 
    } 
} 

class Bar: Foo { 
    override func somethingWasSet() { 
     println("toot toot") 
    } 
} 

Ponieważ nie ma sposobu, aby „override” THE didSet, co pozostaje jest nadrzędne funkcję drugorzędną specjalnie utworzonej do tego celu.

+0

Zgodnie z sugestią @nhgrif, połączyłem oba rozwiązania w jedną odpowiedź. –

+0

Dzięki, pomogło to pęczek. Dziwne, że nie możesz po prostu przesłonić 'didSet'. Jak już przeczytałem, Apple naprawił kilka błędów związanych z 'didSet' nie tak dawno temu. Mam wrażenie, że wciąż mają wiele błędów do naprawienia w odniesieniu do 'didSet'. – Eendje

+0

Nie sądzę, że pozwolenie na obejście obserwatorów nieruchomości najprawdopodobniej będzie w trakcie pracy ... – nhgrif