property observer lazy how example create swift properties override didset

observer - setter swift 4



Anular propiedad observador (3)

Cuando anulo el noise la función, la función es reemplazada por la nueva. Pero cuando anulo una propiedad con un observador, el valor antiguo y el nuevo se ejecutan.

En el patio de recreo:

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

Salida:

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

Pero cuando hago lo mismo con una propiedad con un observador:

En el patio de recreo:

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

Salida:

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

Entonces, ¿cómo se supone que debo anular una propiedad con un observador y cómo evitar que también se ejecuten los valores antiguos?


De la documentación de Swift.

Los observadores willSet y didSet de las propiedades de la superclase se llaman cuando una propiedad se establece en un inicializador de subclase, después de que se haya llamado al inicializador de la superclase. No se invocan mientras una clase establece sus propias propiedades, antes de que se haya llamado al inicializador de superclase.


Los observadores en las subclases solo se agregan a la definida en la superclase.

De la documentación oficial: Overriding

Anulando propiedades

Puede anular una instancia heredada o una propiedad de tipo para proporcionar su propio captador y configurador personalizado para esa propiedad, o agregar observadores de propiedades para permitir que la propiedad de anulación observe cuando cambia el valor de la propiedad subyacente.


Puede anular el set get parte de la propiedad y mover su println allí. De esta manera, Swift no llamará al código original, a menos que llames 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") } } }

Aunque eso no es bonito.

Aquí hay una solución mejor y más simple:

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

Dado que no hay manera de "anular" el didSet , lo que queda es anular una función secundaria especialmente creada para ese propósito.