quand utiliser “willChangeValueForKey” et “didChangeValueForKey”?
J'ai vu ces lignes dans un projet de démo, mais je n'arrivais pas à comprendre pourquoi il l'a fait.
[self willChangeValueForKey:@"names"];
[self didChangeValueForKey:@"names"];
Il appelle didChangeValueForKey immédiatement après willChangeeValueForKey.
Sera-t-elle un sens?
En outre, quand doit-être le bon moment pour appeler ces deux méthodes?
Merci beaucoup!! 🙂
Vous devez vous connecter pour publier un commentaire.
C'est, en fait, un anti-modèle. Vous ne devez pas appeler
-willChangeValueForKey:
suivie par-didChangeValueForKey:
sans intervenir réel changement de propriété. Dans certains cas, cela peut masquer KVO d'autres problèmes dans votre code et de la force des observateurs de mettre à jour leur état liés à la propriété en question. En fin de compte, cependant, vous (ou l'auteur de l'exemple que vous citez) devrait résoudre le reste du code, de sorte que cet anti-modèle est inutile.L'utilisation correcte de
-will|didChangeValueForKey:
est lorsque vous modifiez une propriété sans l'aide de KVC-conforme accesseurs/mutateurs tels que le KVO mécanisme ne serait pas remarqué le changement. Pour un exemple artificiel, envisager de modifier la sauvegarde de variable d'instance pour un attribut directement:KVO observateurs qui s'étaient inscrits pour la notification des changements dans la
bar
bien ne pas recevoir de notification de la modification debar
dans-someMethod
. Pour faire le KVO machines de travail, vous pouvez modifier-someMethod
:Bien sûr, il serait préférable d'utiliser un
@property
de déclaration et d'utiliser KVC-conforme accesseurs/mutateurs (soit codées manuellement ou@synthesized
), mais c'est un exemple artificiel.KVO fonctionneront correctement avec le custom ouvreurs de propriétés; cela a toujours été le cas pour NSObject les classes dérivées. Le moteur d'exécution de machines cherche une invocation de la méthode de définition, et appelle implicitement "willChangeValueForKey" avant l'exécution de l'incubateur, puis appelle implicitement "didChangeValueForKey" après le setter complète.
Vous pouvez désactiver ce comportement automatique si vous souhaitez avoir plus de contrôle fin sur KVO notifications. Comme mentionné ci-dessus, readonly propriétés dont la valeur que vous changer en modifiant la sauvegarde de ivar, ou dont les valeurs sont obtenues par calcul, sont des lieux où vous utiliseriez le manuel des notifications (bien qu'il existe un mécanisme, keyPathsAffectingValueFor, où vous pouvez dire à l'exécution que la valeur d'un bien dépend de la variation d'une autre propriété, et il enverra la notification de modification selon le cas). Pour désactiver le comportement automatique sur la base de chaque propriété, vous les mettez dans une méthode de classe + (BOOL) automaticallyNotifiesObserversOf et retour PAS.
J'ai souvent désactiver automatique KVO notifications, parce que j'ai trouvé que KVO notification est générée lors de l'appel d'un setter, même si la valeur de la propriété est réglée à la même valeur que sa valeur actuelle (par exemple, pas de changement). Je souhaite supprimer l'inutile de notification pour des raisons d'efficacité:
Une bonne discussion peut être trouvé dans la NSKeyValueObserving.h-tête, que vous pouvez parcourir par CMD+clic sur les noms de méthode "willChangeValueForKey" et "didChangeValueForKey" dans XCode.
+keyPathsForValuesAffecting<Key>
au lieu dekeyPathsAffectingValueFor
?Ceux qui ont à faire avec commander manuellement la valeur de clé de l'observation. Normalement, le système prend soin d'elle, mais ils vous permettent un certain contrôle. Regardez cette documentation pour comprendre quand et comment les utiliser ici.
D'accord avec Barry. Je viens de rencontrer le même problème. Voici un cas de l'utilisation de ces deux méthodes.
J'ai déclaré une propriété en lecture seule. Je ne peux donc pas utiliser la propriété de l'accesseur pour modifier la valeur.
Lorsque je veux changer le "var", j'ai besoin d'appeler ces deux méthodes manuellement. Sinon, les observateurs ne seront pas averti.
Edit: m'ignorer, a été la lecture trop rapide Barry est bon 🙂
Être très prudent lors de la substitution
didChangeValueForKey:
. La meilleure chose est de ne pas le faire du tout. Mais si vous le faites, assurez-vous que vous appelezsuper
, sinon vous allez avoir une fuite de mémoire comme démontré ici: https://github.com/jfahrenkrug/KVOMemoryLeaksi vous réécrivez la propriété des méthodes de lecture, merci de l'utiliser.
Ce détachement, en juillet 2013, et il semble ne plus être nécessaire d'appel/didChangeValueForKey. Il semble être pris en charge automatiquement, même si vous avez un custom setter.