views:

387

answers:

3

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?

+8  A: 

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.

NSResponder
A: 

Just use as many operation queues as you like. They are here to separate logical parts of your program. I don't think you should be too concerned about the performance as long as you aren't allocating hundreds of queues per second.

Georg
Website? What does this have to do with websites?
Jim Puls
Thanks, it's still too early in the morning. :)
Georg
A: 

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.

Barry Wark
That's not what the docs say: "The NSBlockOperation class is a concrete subclass of NSOperation that manages the concurrent execution of one or more blocks."http://developer.apple.com/mac/library/DOCUMENTATION/Cocoa/Reference/NSBlockOperation_class/Reference/Reference.html
Jim Puls
Jim, you're absolutely correct. Answer updated. Thanks.
Barry Wark