Question

Je travaillais à travers un exemple dans le chapitre de la concurrence « Plus iPhone 3 de développement, » et ne peut pas se KVO sur un travail de NSOperationQueue comme prévu. Je crée un NSOperationQueue et observer son tableau de operations en utilisant:

NSOperationQueue *newQueue = [[NSOperationQueue alloc] init];
self.queue = newQueue;
[newQueue release];
[queue addObserver:self
        forKeyPath:@"operations"
           options:(NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld)
           context:NULL];

Lorsque le premier NSOperation est ajouté à la file d'attente, je pense qu'il soit ajouté à son tableau de operations sous-jacente (qui la documentation iOS dit est KVO conforme) et, par conséquent, dans le dictionnaire de changement, de trouver une application de NSKeyValueChangeKindKey à NSKeyValueChangeInsertion, avec une application de NSKeyValueChangeNewKey au NSOperation ajouté. Mais je ne voyais pas une sorte de valeur NSKeyValueChangeInsertion.

Je sais que le débogueur est pro et tout, mais dans l'intérêt d'avoir quelque chose d'utile pour copier ici, j'ai commencé ma méthode d'observation avec:

- (void) observeValueForKeyPath:(NSString *)keyPath
                       ofObject:(id)object
                         change:(NSDictionary *)change
                        context:(void *)context {
  NSNumber *kind = [change objectForKey:NSKeyValueChangeKindKey];
  NSObject *newValue = [change objectForKey:NSKeyValueChangeNewKey];
  NSObject *oldValue = [change objectForKey:NSKeyValueChangeOldKey];
  NSIndexSet *indexes = [change objectForKey:NSKeyValueChangeIndexesKey];
  NSLog(@"kind=%d, newValue=%@, oldValue=%@, indexes=%@",
       [kind integerValue], newValue, oldValue, indexes);

Et qui imprime:

2010-11-18 20:01:56.249 Stalled[2692:6f07] kind=1, newValue=(
    "<SquareRootOperation: 0x5f51b40>"
), oldValue=(
), indexes=(null)

2010-11-18 20:01:56.250 Stalled[2692:6f07] kind=1, newValue=(
    "<SquareRootOperation: 0x5f51b40>"
), oldValue=(
    "<SquareRootOperation: 0x5f51b40>"
), indexes=(null)

(SquareRootOperation est tout simplement ma sous-classe de NSOperation qui outrepasse main de façon appropriée et Stalled est tout simplement le nom du projet.) Mais notez que la méthode est appelée deux fois lors de l'insertion d'une seule opération, et les deux fois avec une valeur type de 1, est NSKeyValueChangeSetting, pas NSKeyValueChangeInsertion. De plus, newValue et oldValue semblent être le tableau lui-même, et non pas l'élément ajouté.

Toutes les idées? Merci!

Était-ce utile?

La solution

Les documents disent -operations est KVO conforme, mais ne précise pas à ce détail les notifications seront. Dans la pratique, il semble que vous êtes seulement dit qu'un changement a eu lieu, ainsi aurait de comparer les valeurs anciennes et nouvelles pour savoir ce qui a été inséré.

Ne pas oublier que ces notifications peuvent être envoyés sur un fil!

Autres conseils

La propriété des opérations de NSOperationQueue ne dispose pas d'un type mutable (il retourne NSArray*). Il ne met pas en œuvre donc les indexés à plusieurs méthodes de conformité pour les tableaux mutables de sorte que vous ne verrez jamais les événements d'insertion, seul l'événement de changement pour tout le tableau.

Modifier

Shadowmatter a élevé le fait que l'objet effectivement retourné est un NSMutableArray. Cela ne veut pas, cependant, rien changer. Tout d'abord, la documentation Apple est clair sur la question. Si une méthode est annoncé pour renvoyer un objet immuable, vous devez respecter l'API. Vous ne devez pas utiliser isKindOf: pour savoir si elle est vraiment mutable et vous devez changer définitivement pas.

L'API indique que les opérations de retour type est immuable et vous devez donc le traiter comme tel. Plus important encore pour cette question, car il n'est pas une propriété de collection mutable, il est valeur de la clé de codage conforme aux valeurs du tableau KVC mutables. Pour le respect de la collection indexée mutable, la classe doit

  
      
  • Mettre en oeuvre une ou les deux méthodes -insertObject:in<Key>AtIndex: ou -insert<Key>:atIndexes:.
  •   
  • Mettre en oeuvre une ou les deux méthodes -removeObjectFrom<Key>AtIndex: ou -remove<Key>AtIndexes:.
  •   

(prises directement à partir du guide d'Apple KVC)

Le concepteur de la classe NSOperationQueue conçu la propriété operations comme immuable et donc délibérément omises les méthodes ci-dessus.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top