2009-10-22 6 views
4

Je voudrais surveiller un NSCountedSet pour voir si son contenu change. La mise en place de KVO semble compiler mais cela n'est pas déclenché. Première question: pouvez-vous observer un ensemble? Si oui, y a-t-il quelque chose qui ne va pas dans ce message?KVO sur un NSCountedSet?

[subViewA addObserver:subViewB forKeyPath:@"countedSet" options:0 context:NULL]; 

Je suis vraiment juste essayer de contrôler le nombre de (nombre d'objets) l'ensemble si cela aide.

Edit - voici l'observateur (subViewB):

- (void)observeValueForKeyPath:(NSString *)keyPath 
         ofObject:(id)object 
         change:(NSDictionary *)change 
         context:(void *)context { 
    if ([keyPath isEqual:@"countedSet"]) { 
     NSLog(@"Set has changed"); 
    } 
} 

Edit2 - déplacé le message addObserver du sous-vue à la viewController. J'essaie donc d'obtenir une sous-vue pour observer un NSCountedSet dans un autre des sous-visualisations de viewController. Le chemin clé est "relatif au récepteur" - que je suppose être sous-visualisé.

+1

Comment changez-vous l'ensemble? Utilisez-vous des accesseurs compatibles KVO? – Chuck

+0

countedSet déclaré comme propriété (nonatomic, retain) et correctement synthétisé. J'utilise [myCountedSet addObject: newObject] (et son inverse removeObject :) pour modifier l'ensemble. Ai-je besoin d'une méthode countOfCountedSet peut-être? – Meltemi

Répondre

7

Parler directement à l'objet défini ne génère pas de notifications de modification KVO. Vous devez apporter des modifications à la valeur définie de la propriété d'une manière compatible KVC. Il y a deux manières:

  1. Envoyer le propriétaire un message mutableSetValueForKey:. Cela vous donnera un faux objet qui enveloppe la propriété et publie des notifications KVO autour de chaque modification que vous y apportez.
  2. Implémentez les méthodes set accessor pour la propriété et utilisez-les partout. L'implémentation de chaque méthode parle directement à l'objet set sous-jacent; Tout le code qui n'est pas dans l'une de ces méthodes devrait passer par eux. Ainsi, par exemple, pour ajouter un objet, vous ne devez pas utiliser [myCountedSet addObject:foo] (sauf dans addCountedSetObject:); vous devriez utiliser [self addCountedSetObject:foo] à la place.

Je recommande # 2.Cela peut sembler plus de travail, mais ce n'est pas beaucoup, et ça donne vraiment du bon code.

Plus de détails in the Model Object Implementation Guide et in the Core Data Programming Guide (même si cela n'est pas spécifique aux données de base).

+2

Notez que cela est également vrai pour les tableaux. Si vous mutez un tableau mutable sous KVO, il n'enverra pas de notifications. – Chuck

3

Il existe certainement des méthodes de changement manuel de KVO pour les relations non ordonnées à plusieurs.

Ne voulez-vous pas paramétrer votre options à une valeur différente de zéro? Par exemple, NSKeyValueObservingOptionNew

Aussi KVO Helper de Mike Ash est assez excellent.

Des nsset docs sur addObserver:

objets nsset ne sont pas observables, donc cette méthode soulève une exception lorsque invoquée sur un objet NSSet. Au lieu de en observant un ensemble, observez la relation non-ordonnée à-plusieurs pour laquelle l'ensemble est la collection d'objets connexes.

+0

Je suppose que je ne fais toujours pas tirer mon observateur ... – Meltemi

+0

Je ne sais même pas ce que vous venez d'ajouter "... Au lieu d'observer un ensemble, observez la relation non-ordonnée à-plusieurs pour laquelle le set est la collection d'objets liés "signifie?!? Donc, les ensembles ne peuvent pas être observés? – Meltemi

+0

Mais je n'essaie pas d'observer les "objets NSSet". Je veux juste observer l'ensemble lui-même ... ou plus précisément le "compte" de l'ensemble. Si le nombre d'objets qu'il contient augmente ou diminue, je veux que mon observateur soit averti ... si possible. – Meltemi

0

Quelques choses à vérifier:

  1. est-myController non nil? Si c'est nil, le message addObserver:::: tombe simplement sur le sol silencieusement.
  2. Votre méthode est-elle appelée? Peut-être que c'est appelé, mais pas avec le chemin clé que vous attendez. (Je ne m'attendrais pas à cela non plus, mais ça vaut le coup de vérifier.)
+0

J'ai vérifié myController est non-nul. Même déplacé certaines choses mais en vain ... et NON, la méthode observeValueForKeyPath N'EST PAS du tout appelée. le câblage doit donc être visse. – Meltemi

Questions connexes