I need in my application to download directories and their content. So I decided to implement a NSOperationQueue and I subclassed NSOperation to implement NSURLRequest etc..
Add a "Done" NSOperation
which has all other NSOperations
for one directory as dependency.
Something like this:
NSInvocationOperation *doneOp = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(done:) object:nil];
NSInvocationOperation *op1 = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(doSomething:) object:nil];
[queue addOperation:op1];
[doneOp addDependency:op1];
NSInvocationOperation *op2 = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(doSomething:) object:nil];
[queue addOperation:op2];
[doneOp addDependency:op2];
NSInvocationOperation *op3 = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(doSomething:) object:nil];
[queue addOperation:op3];
[doneOp addDependency:op3];
[queue addOperation:doneOp];
doneOp
will only run after op1
, op2
and op3
have finished executing.
[opQueue operationCount]
Hope this helps
One approach would be to create some sort of Directory class with a properties such as loadedCount (initially 0) and fileCount (initialized to however many files are in the directory) and create a dictionary mapping each NSOperation to the appropriate Directory before adding the operation to the queue. Inside your callback for isFinished, you could pull the Directory object for the given NSOperation out of the dictionary and increment the directory.loadedCount by 1. If your directory.loadedCount == directory.fileCount, trigger an update to the UI.
You can refactor your code to avoid enqueuing all requests at once. Enqueue only requests for a single directory at a time. When operationCount
reaches zero, you can be sure that all the requests either completed or failed, update the UI and enqueue the requests for the next directory. Proceed until the array of directories is empty.
The advantages are: