Domanda

stavo lavorando con un esempio nel capitolo concorrenza di "Più iPhone 3 Development," e non può ottenere KVO su un lavoro NSOperationQueue come previsto. Creo un NSOperationQueue e osservo la sua gamma operations utilizzando:

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

Quando il primo NSOperation viene aggiunto alla coda, mi aspetto di essere aggiunto alla sua gamma operations sottostante (che la documentazione iOS dice è KVO-compliant) e, di conseguenza, nel dizionario cambiamento, di trovare una mappatura da NSKeyValueChangeKindKey a NSKeyValueChangeInsertion, insieme a una mappatura da NSKeyValueChangeNewKey alla NSOperation aggiunto. Ma io non vedevo alcun tipo di valore NSKeyValueChangeInsertion.

So che il debugger è pro e tutti, ma nell'interesse di avere qualcosa di utile per copiare qui, ho iniziato il mio metodo di osservatore presso:

- (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);

E che le stampe:

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 è semplicemente la mia sottoclasse di NSOperation che sostituzioni main appropriato e Stalled è semplicemente il nome di progetto). Ma nota che il metodo è chiamato due volte dopo l'inserimento di una singola operazione, e entrambe le volte con un valore genere di 1, che è NSKeyValueChangeSetting, non NSKeyValueChangeInsertion. Inoltre, newValue e oldValue sembrano essere la matrice stessa, non l'elemento aggiunto.

Tutte le idee? Grazie!

È stato utile?

Soluzione

La documentazione dire -operations è KVO-compatibile, ma non si specifica a quello che i dettagli saranno le notifiche. In pratica, a quanto pare si è detto solo che si è verificato un cambiamento, così avrebbe dovuto confrontare i vecchi e nuovi valori per scoprire ciò che è stato inserito.

Non dimenticate che queste notifiche possono essere inviate a voi su qualsiasi thread!

Altri suggerimenti

La proprietà operazioni di NSOperationQueue non ha un tipo mutabile (restituisce NSArray*). Essa, pertanto, non attuare i numerosi to-metodi di conformità indicizzati per gli array mutabili in modo che non vedrai mai gli eventi di inserimento, solo l'evento cambiamento per l'intero array.

Modifica

Shadowmatter ha portato il fatto che l'oggetto effettivamente restituito è un NSMutableArray. Questo non significa, tuttavia, cambia nulla. In primo luogo, la documentazione di Apple è chiara sulla questione. Se un metodo è pubblicizzato per restituire un oggetto immutabile, è necessario rispettare l'API. È vietato utilizzare isKindOf: per scoprire se è davvero mutevole e non si deve assolutamente cambiare.

L'API dice che le operazioni di ritorno Tipo è immutabile e si devono quindi trattare come tale. Ancora più importante per questa domanda, in quanto non è una proprietà della raccolta mutabile, non è valore di chiave di codifica conforme per i valori KVC matrice mutevoli. Per mutevole conformità raccolta indicizzata, la classe deve

  
      
  • implementare uno o entrambi i metodi -insertObject:in<Key>AtIndex: o -insert<Key>:atIndexes:.
  •   
  • implementare uno o entrambi i metodi -removeObjectFrom<Key>AtIndex: o -remove<Key>AtIndexes:.
  •   

(presa direttamente dalla guida di Apple KVC)

Il progettista della classe NSOperationQueue progettato la proprietà operations come immutabile e quindi volutamente omesso i metodi di cui sopra.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top