Get notification when NSOperationQueue finishes all tasks
asynchronous, iphone, notifications, nsoperation, queue
Solution
Use KVO to observe the `operations` property of your queue, then you can tell if your queue has completed by checking for `[queue.operations count] == 0`.
Somewhere in the file you're doing the KVO in, declare a context for KVO like this (more info):
static NSString *kQueueOperationsChanged = @"kQueueOperationsChanged";
When you setup your queue, do this:
[self.queue addObserver:self forKeyPath:@"operations" options:0 context:&kQueueOperationsChanged];
Then do this in your `observeValueForKeyPath`:
- (void) observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object
change:(NSDictionary *)change context:(void *)context
{
if (object == self.queue && [keyPath isEqualToString:@"operations"] && context == &kQueueOperationsChanged) {
if ([self.queue.operations count] == 0) {
// Do something here when your queue has completed
NSLog(@"queue has completed");
}
}
else {
[super observeValueForKeyPath:keyPath ofObject:object
change:change context:context];
}
}
(This is assuming that your `NSOperationQueue` is in a property named `queue`)
At some point before your object fully deallocs (or when it stops caring about the queue state), you'll need to unregister from KVO like this:
[self.queue removeObserver:self forKeyPath:@"operations" context:&kQueueOperationsChanged];
Addendum: iOS 4.0 has an `NSOperationQueue.operationCount` property, which according to the docs is KVO compliant. This answer will still work in iOS 4.0 however, so it's still useful for backwards compatibility.
Problem
`NSOperationQueue` has `waitUntilAllOperationsAreFinished`, but I don't want to wait synchronously for it. I just want to hide progress indicator in UI when queue finishes. What's the best way to accomplish this? I can't send notifications from my `NSOperation`s, because I don't know which one is going to be last, and `[queue operations]` might not be empty yet (or worse - repopulated) when notification is received.