iOS – How to know when NSOperationQueue finish processing a few operations?
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…
The problem is I add all the operations at once and I can’t figure out when all the files for one directory are downloaded in order to update the UI and enable this specific directory.
Now I have to wait that all the files from all the directories are downloaded in order to update the UI.
I already implemented key-value observing for the operationCount of the NSOperationQueue and the isFinished of the NSOperation but I don’t know when a directory has all the files in it !
Do you have any idea ?
Thanks a lot
- Continue operation when app did enter background on iOS
- What is the difference between NSInvocationOperation and NSBlockOperation
- NSOperation and NSOperationQueue working thread vs main thread
- Referencing an NSOperation object in its own completion block with ARC
- NSOperation and NSNotificationCenter on the main thread
- CKFetchRecordsOperation + CKQueryOperations … what am I missing?
4 Solutions Collect From Internet About “iOS – How to know when NSOperationQueue finish processing a few operations?”
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
op3 have finished executing.
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:
- relative simplicity
- you don’t have to query the file system only to figure out what has been downloaded
- if need be, you can re-enqueue failed requests without changing other logic.
- objective-c code to right pad a NSString?
- Does iPhone support hardware-accelerated AES Encryption?
- Cannot change WKWebView's scroll rate on iOS 9 beta / 9.3
- Facebook iOS SDK – creating user owned objects and publishing an open graph story without a backend server
- Swift can't retrieve images from parse.com
- Unity receive event from object c
- How to get file path in iPhone app
- How to add a button to a table view cell in iOS?
- Pass data through navigation back button
- Make UITableView not scrollable and adjust height to accommodate all cells
- How can we handle headphone play/pause button events in foreground in ios
- How to create unique arrays of a given size from an array in Swift?
- OAuth access Token fails while accessing twitter from iOS 5
- Xcode 6.3.2 or 6.4beta Localization failed to read a strings file
- How do I Increment an NSDate object in Objective-C