web-dev-qa-db-fra.com

Remplacer l'observateur de propriété

Lorsque je remplace la fonction noise, la fonction est remplacée par la nouvelle. Mais lorsque je remplace une propriété par un observateur, l'ancienne et la nouvelle valeur sont exécutées.

Dans la cour de récréation:

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

Sortie:

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

Mais quand je fais la même chose avec une propriété avec un observateur:

Dans la cour de récréation:

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

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

Sortie:

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

Alors, comment suis-je censé remplacer une propriété par un observateur et comment empêcher les anciennes valeurs d'être également exécutées?

16
Eendje

Vous pouvez remplacer les parties set et get de la propriété et y déplacer votre println. De cette façon, Swift n'appellera pas le code d'origine - à moins d'appeler 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")
        }
    }
}

Ce n'est pas joli, cependant.

Voici une solution meilleure - et plus simple -:

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

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

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

Comme il n’existe aucun moyen de "remplacer" la didSet, il ne reste plus qu’à remplacer une fonction secondaire spécialement créée à cet effet.

28
Jean Le Moignan

De la documentation Swift

Les observateurs willSet et didSet des propriétés de la superclasse sont appelés lorsqu'une propriété est définie dans un initialiseur de sous-classe, après l'appel de l'initialiseur de superclasse. Ils ne sont pas appelés lorsqu'une classe définit ses propres propriétés, avant l'appel de l'initialiseur de superclasse.

0
Enrico Cupellini