I'm working with some code that does a bunch of asynchronous operating with various callbacks; Snow Leopard has made this incredibly easy with blocks and GCD.
I'm calling NSTask
from an NSBlockOperation
like so:
[self.queue addOperationWithBlock:^{
NSTask *task = [NSTask new];
NSPipe *newPipe = [NSPipe new];
NSFileHandle *readHandle = [newPipe fileHandleForReading];
NSData *inData = nil;
[task setLaunchPath:path];
[task setArguments:arguments];
[task launch];
while ((inData = [readHandle availableData]) && [inData length]) {
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
// callback
}];
}
[task waitUntilExit];
}];
This approach works perfectly. It's like magic, as long as my callbacks handle the concurrency correctly.
Now, I want to be able to coalesce some of these calls; this is inside a model object's "refresh" method and may take a long time to complete. Having the user pound on the refresh button shouldn't tie up the machine and all that.
I can see an implementation dilemma here. I can make a whole bunch of queues - one per call type - and set their concurrent operation counts to 1 and then call -cancelAllOperations
whenever it's time for a new call.
Alternately, I could do some more manual bookkeeping on which calls are currently happening and manage a single queue per model object (as I'm doing) or I could go even further and use a global queue.
How heavy is NSOperationQueue
? Is creating a lot of queues a bad architecture decision? Is there a better way to coalesce these tasks?
If you're concerned about performance, don't guess: measure and then fix any bottlenecks you find. Adding queues is simple; try it and see what Instruments tells you about the effect on performance.
The main reason for creating multiple queues is in case you have some reason for wanting to start and stop them. If you just want to get the benefits of libdispatch, you can get that by just adding operations to the main queue.
You can add multiple blocks to an NSBlockOperation which will be executed concurrently and can be canceled by canceling the containing operation. As long as your individual tasks don't have to be serialized, this may work.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With