Ändern Wörterbuch Werte falsch bei der Verwendung von KVO mit NSOperationQueue?
-
26-09-2019 - |
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!
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.