Vérifier si une valeur est modifiée à l'aide de KVO dans Swift 3

Je voudrais savoir quand un ensemble de propriétés d'un objet Swift changements. Auparavant, j'avais mis en place cette en Objective-C, mais je vais avoir quelques difficultés à le convertir à Swift.

Mon précédent code Objective-C est:

- (void) observeValueForKeyPath:(NSString*)keyPath ofObject:(id)object change:(NSDictionary*)change context:(void*)context {
    if (![change[@"new"] isEqual:change[@"old"]])
        [self edit];
}

Mon premier passage à une solution Swift était:

override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
    if change?[.newKey] != change?[.oldKey] {    //Compiler: "Binary operator '!=' cannot be applied to two 'Any?' operands"
        edit()
    }
}

Cependant, le compilateur se plaint: "opérateur Binaire '!=' ne peut pas être appliqué à deux'?' opérandes"

Ma deuxième tentative:

override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
    if let newValue = change?[.newKey] as? NSObject {
        if let oldValue = change?[.oldKey] as? NSObject {
            if !newValue.isEqual(oldValue) {
                edit()
            }
        }
    }
}

Mais, en pensant à cela, je ne pense pas que cela va fonctionner pour les primitives de swift des objets tels que des Int qui (je suppose) n'héritent pas de NSObject et à la différence de l'Objective-C version ne sera pas en boîte en NSNumber lorsqu'il est placé dans le changement dictionnaire.

Donc, la question est de savoir comment dois-je faire apparemment tâche facile de déterminer si une valeur est modifiée à l'aide du KVO dans Swift3?

Aussi, question bonus, comment puis-je faire usage de la 'de l'objet' variable? Il ne me laisse pas changer le nom et bien sûr, n'aime pas les variables avec les espaces.

Assurez-vous aussi de voir ce réponse par Rob
Remarque il y a un Swift4 bug lorsque vous utilisez .initial. Pour une solution reportez-vous à here

OriginalL'auteur aepryus | 2016-10-19