46 votes

Approche Swift 4 pour observeValue (forKeyPath: ...)

J'ai essayé de trouver un exemple, mais ce que j'ai vu ne fonctionne pas dans mon cas.

Quel serait l'équivalent du code suivant:

 object.addObserver(self, forKeyPath: "keyPath", options: [.new], context: nil)

override public func observeValue(
    forKeyPath keyPath: String?,
    of object: Any?, 
    change: [NSKeyValueChangeKey : Any]?, 
    context: UnsafeMutableRawPointer?) {

}
 

Le code ci-dessus fonctionne, mais je reçois un avertissement de SwiftLink:

Préférez la nouvelle API KVO basée sur des blocs avec des chemins de clé lorsque vous utilisez Swift 3.2 ou une version ultérieure.

Je l'apprécie si vous pouvez me diriger dans la bonne direction.

103voto

Matias Pequeno Points 876

Swift 4 introduit une famille de béton -Clés types de Tracé, une nouvelle Clé-Expression de Chemin d'accès pour les produire et à une nouvelle fermeture de la base d'observer fonction disponible pour les classes qui en héritent NSObject.

L'utilisation de ce nouvel ensemble de fonctionnalités, votre exemple peut maintenant être exprimé beaucoup plus succinctement:

self.observation = object.observe(\.keyPath) { 
    [unowned self] object, change in
    self.someFunction()
}

Les Types Impliqués

Clé-Chemin de la grammaire

La générale de la grammaire d'une Expression de Chemin suit la forme \Type.keyPathType est un type concret nom (incl. tous les paramètres génériques), et keyPath d'une chaîne d'un ou de plusieurs propriétés, des indices, ou en option chaînage forcés/déballage postfixes. En outre, si le chemin d'accès clé de Type peut être déduit du contexte, il peut être gommés, résultant en une plus lapidaire \.keyPath.

Ce sont toutes valides-Clés Expressions de Chemin d'accès:

\SomeStruct.someValue
\.someClassProperty
\.someInstance.someInnerProperty
\[Int].[1]
\[String].first?.count
\[SomeHashable: [Int]].["aStringLiteral, literally"]!.count.bitWidth

La propriété

Vous êtes le propriétaire de l' NSKeyValueObservation de l'instance de l' observe fonction retourne une valeur, un sens, vous n'avez pas à addObserver ni removeObserver plus; plutôt, vous gardez une référence forte à elle pour aussi longtemps que vous avez besoin de votre sens de l'observation l'observation.

Vous êtes pas tenus d' invalidate() soit: c' deinit gracieusement. Donc, vous pouvez la laisser vivre jusqu'à ce que l'instance tenue il meurt, l'arrêter manuellement en niling la référence, ou même invoquer invalidate() si vous avez besoin de garder votre exemple vivant pour certains malodorante raison.

Mises en garde

Comme vous l'avez remarqué, l'observation encore se cache à l'intérieur de l'enceinte de Cacao du KVO mécanisme, par conséquent, il est seulement disponible à l'Obj-C classes et rapide des classes héritant NSObject (tous les Swift-dev type préféré) avec l'ajout de l'exigence que toute la valeur que vous avez l'intention d'observer, doivent être marquées comme @objc (tous les Swift-dev préférée de l'attribut) et a déclaré dynamic.

Cela étant dit, l'ensemble du mécanisme est félicité de l'amélioration, en particulier parce qu'il parvient à Swiftify observation importés NSObjects de modules de nous peut arriver à être requis pour l'utilisation (par exemple. Foundation), et sans risque d'affaiblissement de la puissance expressive nous travaillons si dur à obtenir avec chaque frappe de touche.

Comme une note, Clé de Chemin de Chaîne Expressions sont encore nécessaires pour accéder dynamiquement NSObjects'propriétés de KVC ou appelez - value(forKey(Path):)

Au-delà de KVO

Il y a beaucoup plus d'-Clés Expressions de Chemin que KVO. \Type.path expressions peuvent être stockées en tant que KeyPath objets pour les réutiliser ultérieurement. Ils viennent dans l'écriture, partielle et le type effacé saveurs. Ils peuvent augmenter la puissance expressive de getter/setter fonctions conçues pour la composition, pour ne pas mentionner le rôle qu'ils jouent en permettant à ceux avec la plus forte de l'estomac pour se plonger dans le monde de concepts fonctionnels comme des Lentilles et des Prismes. Je vous suggère de vérifier les liens vers le bas ci-dessous pour en apprendre davantage sur les nombreuses de développement portes, ils peuvent ouvrir.

Liens:

Clé-Chemin Expression @ docs.swift.org

KVO docs @ Apple

Swift Évolution Smart KeyPaths proposition

Ole Begemann du Whats-new-in-Swift-4 aire de jeux avec les Principaux exemples de Chemin

La WWDC 2017 Vidéo: nouveautés de la Fondation 4:35 pour SKP et 19:40 pour le KVO.

10voto

barbarity Points 1847

Pour ajouter quelque chose à la réponse que j'ai vécu s'écrase sur mon application lors de l'utilisation de cette méthode dans iOS 10.

Dans iOS 10, vous avez encore besoin de supprimer l'observateur avant de la désallocation de la classe ou sinon vous obtiendrez un crash NSInternalInconsistencyException déclarant que:

Un exemple A de la Classe C a été libérée, tandis que la valeur de la clé, les observateurs étaient encore inscrits.

Pour éviter ce plantage. Réglez simplement l'observateur de la propriété que vous utilisez pour nil.

deinit {
    self.observation = nil
}    

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X