Измените значения словаря неправильно при использовании KVO с NSOPERATIONQUUE?
-
26-09-2019 - |
Вопрос
Я работал в примере в главе параллелизма «Больше разработки iPhone 3», и не может получить KVO на NSOperationQueue
работаю как ожидалось. Я создаю АН NSOperationQueue
и соблюдайте его operations
Массив с использованием:
NSOperationQueue *newQueue = [[NSOperationQueue alloc] init];
self.queue = newQueue;
[newQueue release];
[queue addObserver:self
forKeyPath:@"operations"
options:(NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld)
context:NULL];
Когда первый NSOperation
добавляется в очередь, я ожидаю, что он будет добавлен к его базовому operations
массив (который документация iOS говорит, что KVO-совместимый) и, следовательно, в словаре Изменить, чтобы найти отображение из NSKeyValueChangeKindKey
к NSKeyValueChangeInsertion
, наряду с сопоставлением от NSKeyValueChangeNewKey
к добавленному NSOperation
. Отказ Но я не видел какую-либо ценность NSKeyValueChangeInsertion
.
Я знаю, что Debugger Pro и все, но в интересах иметь что-то полезное копировать здесь, я начал свой метод наблюдателя с:
- (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);
И это отпечатки:
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
просто мой подкласс NSOperation
это переопределено main
соответствующим образом и Stalled
это просто имя проекта.) Но обратите внимание, что метод называется дважды при вставке одной операции, и оба раза с доброй стоимостью 1, что NSKeyValueChangeSetting
, нет NSKeyValueChangeInsertion
. Отказ Кроме того, newValue
а также oldValue
Кажется, сам массив, а не добавленный товар.
Есть идеи? Спасибо!
Решение
Документы говорят -operations
КВО-совместимый, но не указывайте на какую деталь уведомления будут. На практике, кажется, вам говорят, что произошло только изменения, поэтому придется сравнить старые и новые значения, чтобы узнать, что было вставлено.
Не забывайте, что эти уведомления могут быть отправлены вам в любой поток!
Другие советы
Свойство операций NSOperatueue не имеет смешанного типа (он возвращает NSArray*
). Поэтому он не реализует индексированные методы соответствия для соревновательных массивов, поэтому вы никогда не увидите события вставки, только событие изменения для всего массива.
Редактировать
Shadowmatter поднял тот факт, что на самом деле возвращенный объект является NSMutableArray
. Отказ Это не, однако, ничего не изменит. Во-первых, Документация Apple ясно по этому вопросу. Если метод рекламируется для возврата неизменного объекта, вы должны уважать API. Вы не должны использовать isKindOf:
Чтобы узнать, действительно ли это действительно мусор, и вы обязательно не изменяете его.
API говорит, что тип возврата операций неизменен, и поэтому вы должны относиться к нему как таковое. Что еще более важно для этого вопроса, так как это не сметная коллекция имущество, это не Ключевое значение для кодирования соответствует для соревноваемых значений массива KVC. Для соответствия соревнованию индексированного сбора, класс должен
- Реализовать один или оба метода
-insertObject:in<Key>AtIndex:
или-insert<Key>:atIndexes:
.- Реализовать один или оба метода
-removeObjectFrom<Key>AtIndex:
или-remove<Key>AtIndexes:
.
(взяты непосредственно из руководства Apple KVC)
Дизайнер NSOperationQueue
Класс спроектирован operations
Имущество как неизменное и поэтому намеренно разработано вышеуказанные методы.