Frage

Ich arbeite an einem Beispiel in der Gleichzeitigkeit Kapitel von „Mehr iPhone 3 Entwicklung“ und kann nicht KVO auf einer NSOperationQueue wie erwartet funktioniert. Ich eine NSOperationQueue erstellen und beobachten seine operations Array mit:

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

Wenn die erste NSOperation der Warteschlange hinzugefügt wird, erwarte ich ihn auf sein operations Array hinzugefügt werden (die die iOS-Dokumentation sagt, ist KVO-konform) und damit im Wechsel Wörterbuch, eine Zuordnung von NSKeyValueChangeKindKey finden NSKeyValueChangeInsertion, zusammen mit einer Abbildung von NSKeyValueChangeNewKey zu dem zusätzlichen NSOperation. Aber ich war nicht jede Art von Wert NSKeyValueChangeInsertion zu sehen.

ich weiß, der Debugger ist Pro und alle, aber im Interesse der etwas Nützliches mit hier zu kopieren, begann ich meinen Beobachter Methode mit:

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

Und die Drucke:

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 ist einfach meine Unterklasse von NSOperation dass Überschreibungen main angemessen und Stalled ist einfach der Projektname.) Aber beachten Sie, dass die Methode zweimal aufgerufen wird, eine einzelne Operation beim Einführen, und beide Male mit einer Art Wert von 1, die NSKeyValueChangeSetting ist, nicht NSKeyValueChangeInsertion. Zusätzlich newValue und oldValue scheinen das Array selbst, nicht das Element hinzugefügt werden.

Irgendwelche Ideen? Dank!

War es hilfreich?

Lösung

Die docs sagen -operations ist KVO-konform, aber nicht angeben, was Detail Mitteilungen sein wird. In der Praxis scheint es, Sie sind nur gesagt, dass eine Änderung aufgetreten ist, würden die alten und neuen Werte zu vergleichen, so haben, um herauszufinden, was eingefügt wurde.

Vergessen Sie nicht, dass diese Benachrichtigungen können auf jedem Thread an Sie versendet!

Andere Tipps

Die Operationen Eigenschaft NSOperationQueue keine wandelbaren Typ haben (es gibt NSArray*). Es ist daher nicht implementieren die indizierten to-many Compliance Methoden für veränderbare Arrays so dass Sie nie die Insert-Ereignisse sehen, nur das Änderungsereignis für die gesamte Array.

Bearbeiten

Shadowmatter hat die Tatsache gebracht, dass die tatsächlich zurückgegebene Objekt ein NSMutableArray ist. Dies gilt jedoch nicht, etwas ändern. Erstens Apples Dokumentation zu diesem Thema klar. Wenn eine Methode beworben wird ein unveränderliches Objekt zurückgeben, müssen Sie die API respektieren. Sie müssen nicht isKindOf: verwenden, um herauszufinden, ob es wirklich wandelbar ist und Sie müssen auf jeden Fall nicht geändert werden.

Die API sagt die Operationen Rückgabetyp unveränderlich ist, und Sie müssen es daher als solche behandeln. Noch wichtiger ist für diese Frage, da es nicht eine veränderliche Sammlung Eigenschaft ist, ist es nicht Schlüsselwert Codierung kompatible für die änderbaren Array KVC Werte. Für wandelbar indizierte Compliance, hat die Klasse

  
      
  • Implementieren eines oder beide der Methoden -insertObject:in<Key>AtIndex: oder -insert<Key>:atIndexes:.
  •   
  • Implementieren eines oder beide der Methoden -removeObjectFrom<Key>AtIndex: oder -remove<Key>AtIndexes:.
  •   

(direkt aus dem Apple KVC Führer genommen)

Der Designer der NSOperationQueue Klasse entwickelt, um die operations Eigenschaft als unveränderlich und daher bewusst die oben genannten Methoden weggelassen.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top