0
votes

I realize that this is a problem others have had before me but I seem unable to find a good solution. My problem is that I want to loop through a number of operations stored in a NSOperationQueue, and when all operations have finished I would like to post a notification. The notification starts a final process that relies on all of the operations to have finished. However, my notification is sent several times prior to the operations have finished. This is my approach:

self.queueFinished=FALSE;
[self createFileobjectsForDirectories:self.mymode];

This results in an array of operations (self.arrayOfOperations) which is further used:

[self.myFileobjectsQueue addOperations:self.arrayOfOperations waitUntilFinished:NO];

NSInvocationOperation *completionOperation = [[NSInvocationOperation alloc] initWithTarget:self
                                                                                  selector:@selector(runLastOperation:)
                                                                                    object:start];
for (NSOperation *myOp in self.myFileobjectsQueue.operations){
    [completionOperation addDependency:myOp];
}
[completionOperation setQueuePriority:NSOperationQueuePriorityVeryLow];
[self.myFileobjectsQueue addOperation:completionOperation];


-(void) runLastOperation:(NSDate*) start {
    [[NSNotificationCenter defaultCenter] postNotificationName:kCompareFinished object:nil userInfo:nil];
    self.queueFinished=TRUE;
}

I have tried several approaches to observing when my queue has finished as suggested elsewhere, without success. It is almost like the notifications are called when the queue is empty, but prior to operations have finished their tasks. But according to Apple documentation the operation will not be removed from the queue until the isFinished flag is TRUE. I am running concurrent operations using the regular main function in a subclass of NSOperation. Perhaps I am misunderstanding something here, but suggestions for how to make sure that not only the queue is empty, but to also make sure that the operations have finished would be greatly appreciated.

Cheers, Trond

1

1 Answers

0
votes

It doesn't seem like you need a notification (at least not to trigger the final processing). Instead, create a new operation, make it dependent upon all of the other operations that you add for your processing and then add it to the queue. Then it will run only once all of the other operations are complete.


You're correct about isFinished determining when the operation is finished. One thing to consider is that any completionBlock added to an operation is run after the operation has completed (not just before it completes).