I was working through an example in the concurrency chapter of "More iPhone 3 Development," and can't get KVO on an NSOperationQueue
working as expected. I create an NSOperationQueue
and observe its operations
array using:
NSOperationQueue *newQueue = [[NSOperationQueue alloc] init];
self.queue = newQueue;
[newQueue release];
[queue addObserver:self
forKeyPath:@"operations"
options:(NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld)
context:NULL];
When the first NSOperation
is added to the queue, I expect it to be added to its underlying operations
array (which the iOS documentation says is KVO-compliant) and hence, in the change dictionary, to find a mapping from NSKeyValueChangeKindKey
to NSKeyValueChangeInsertion
, along with a mapping from NSKeyValueChangeNewKey
to the added NSOperation
. But I wasn't seeing any kind of value NSKeyValueChangeInsertion
.
I know the debugger is pro and all, but in the interest of having something useful to copy here, I started my observer method with:
- (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);
And that prints:
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
is simply my subclass of NSOperation
that overrides main
appropriately, and Stalled
is simply the project name.) But note that the method is called twice upon inserting a single operation, and both times with a kind value of 1, which is NSKeyValueChangeSetting
, not NSKeyValueChangeInsertion
. Additionally, newValue
and oldValue
seem to be the array itself, not the item added.
Any ideas? Thanks!
The docs say -operations
is KVO-compliant, but don't specify to what detail the notifications will be. In practice, it seems you are only told that a change has occurred, so would have to compare the old and new values to find out what was inserted.
Don't forget that these notifications can be sent to you on any thread!