2011-11-27 2 views
3

J'ai certaines valeurs qui sont calculées sur des collections, et peuvent ou ne peuvent pas être affichées (et peuvent donc avoir ou non un observateur) à un moment donné. Je préférerais ne pas avoir à suivre tous les membres de la collection si personne n'observe mes valeurs calculées. Puis-je savoir si quelqu'un observe actuellement une valeur et puis-je savoir quand il commence à observer?Y at-il un moyen de savoir quand KVO commence/finit pour une valeur particulière?

Je sais que pour un objet donné foo je peux utiliser [foo observationInfo] pour obtenir une liste des observateurs avec des chemins clés enregistrés avec une racine à foo, mais qui ne reçoit pas automatiquement tous les chemins Foo (en fait, il obtient seulement ceux enregistrés pour observer la clef de soi de foo).

Répondre

3

Ce n'est pas une bonne idée du point de vue de la conception. Si vous insistez vraiment pas mettre à jour le contenu quand personne a besoin d'eux (ce qui pourrait être un cas légitime, par exemple, si les mises à jour sont chers), vous pouvez introduire des méthodes pour démarrer/arrêter les mises à jour:

- (void) beginUpdatingContents; 
- (void) endUpdatingContents; 

Ceux-ci devraient être lié à un compteur à l'intérieur de la classe et si le compteur est> 0, vous savez que quelqu'un veut garder le contenu à jour. Cette solution est explicite et donc meilleure que la magie silencieuse avec KVO.

+2

Attendez, si le problème a été introduit par la magie KVO silencieuse, la réponse n'est pas ** encore plus silencieuse magie KVO **? – Stripes

+0

Il y a un point où il y a tout simplement trop de magie KVO silencieuse. Avec votre solution, je pense que nous pourrions être près :) – zoul

+0

Eh bien, mon premier commentaire était 85% blague. L'autre 15% est que ce projet était réellement destiné à être une expérience d'apprentissage iOS et Core Data pour moi, donc si je code la version "plus magique" et décide que c'est "trop" magique, je suis en fait plus proche de atteindre mes objectifs alors si je joue juste en toute sécurité. – Stripes

2

Si vous voulez plus de magie, pourquoi ne pas surcharger addObserver:forKeyPath:options:context: et removeObserver:forKeyPath: et suivre ce qui vous observe encore? La manière dont je l'ai fait dans le passé est de créer des objets wrapper (je les ai appelés bindings) qui configurent le KVO et s'enregistrent eux-mêmes avec la cible. Ainsi, un utilisateur appellerait MyBinding *binding = [targetObject bindKeyPath:@"foo" ...] et plus tard [binding detach]. Vous avez ensuite la liaison utiliser KVO sous le capot et garder une liste d'eux-mêmes afin que vous sachiez quand il est vide.

Questions connexes