Let’s say you’re making HTTP requests and handling responses as we described last time. Parsing the results is usually pretty easy, but what happens when you have a large blob of data, be it XML or JSON or whatever? Any lengthly processing on the main thread, more than a couple hundred milliseconds, will introduce a noticeable hiccup in the UI. Adding a worker thread would help, but perhaps the easiest method is to use the non-blocking NSOperationQueue. With NSOperationQueue you simply package up the work to be done into an NSOperation instance and add it to the queue.

Your application can create any number of NSOperationQueue objects, but the documentation suggests there is a practical limit to how many operations are executing at any given time. Specifically, adding additional queues does not mean you can execute additional operations. I find that a single queue is usually sufficient. Having access to a global operation queue means you can add, suspend, and cancel operations as needed. Add something like this to ApplicationDidFinishLaunching:

// Create the shared operation queue

sharedOperationQueue = [[NSOperationQueuealloc] init];


Then you can begin adding operations to the queue. Take the request handler callback we used last time, and modify it slightly, like this:

id delegate = self;

myConnectionController* connectionController = [[[myConnectionController alloc] initWithDelegate:delegate

selSucceeded:@selector(connectionSucceededWrapper:)

selFailed:@selector(connectionFailed:)] autorelease];

[myConnectionController startRequestForURL:[NSURLURLWithString:@"http://request.org/somequery.php"]];


Notice all we did was change the selSucceeded selector to connectionSucceededWrapper:. The new wrapper method creates and adds the operation to the queue, as follows:

- (void)connectionSucceededWrapper:(NSMutableData*)data

{

  NSInvocationOperation* theOp = [[NSInvocationOperation alloc] initWithTarget:self

     selector:@selector(connectionSucceeded:) object:data];

  [sharedOperationQueue addOperation:theOp];

}

There’s no need to change the connectionSucceeded callback. This is presumably where you do the parsing, or any lengthy processing, and probably post notification that the model has changed. Perhaps you are loading thumbnail images and need to cache the image data and notify a table view to refresh a cell. Because the NSOperationQueue operates in a separate thread your UI will not stutter. However, since it executes on another thread, if you need to update any UI elements make sure to use performSelectorOnMainThread: when doing so.

This post is part of iDevBlogADay, a group of indie iOS development blogs featuring two new posts per day. You can keep up with iDevBlogADay through the web site,RSS feed, or Twitter.