NSOperationQueue And NSOperation
According to Apple…
TheNSOperation
andNSOperationQueue
classes alleviate much of the pain of multi-threading, allowing you to simply define your tasks, set any dependencies that exist, and fire them off. Each task, or operation, is represented by an instance of anNSOperation
class; theNSOperationQueue
class takes care of starting the operations, ensuring that they are run in the appropriate order, and accounting for any priorities that have been set.
The way it works is, you create a new NSOperationQueue and add NSOperations to it. The NSOperationQueue creates a new thread for each operation and runs them in the order they are added (or a specified order (advanced)). It takes care of all of the autorelease pools and other garbage that gets confusing when doing multithreading and greatly simplifies the process.
Here is the process for using the NSOperationQueue.
- Instantiate a new NSOperationQueue object
- Create an instance of your NSOperation
- Add your operation to the queue
- Release your operation
There are a few ways to work with NSOperations. Today, I will show you the simplest one: NSInvocationOperation. NSInvocationOperation is a subclass of NSOperation which allows you to specify a target and selector that will run as an operation.
Here is an example of how to execute an NSInvocationOperation:
NSOperationQueue *queue = [NSOperationQueue new];
NSInvocationOperation *operation = [[NSInvocationOperation alloc] initWithTarget:self
selector:@selector(methodToCall)
object:objectToPassToMethod];
[queue addOperation:operation];
[operation release];
This will call the method “methodToCall” passing in the object “objectToPassToMethod” in a separate thread. Let’s see how this can be added to our code above to make it run smoother.
Example of tableView
- (void) loadDataFromServer { /* Operation Queue init (autorelease) */ NSOperationQueue *queue = [NSOperationQueue new]; /* Create our NSInvocationOperation to call loadDataWithOperation, passing in nil */ NSInvocationOperation *operation = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(loadDataWithOperation) object:nil]; /* Add the operation to the queue */ [queue addOperation:operation]; [operation release]; } - (void) loadDataWithOperation { NSURL *dataURL = [NSURL URLWithString:@"http://icodeblog.com/samples/nsoperation/data.plist"]; NSArray *tmpp_array = [NSArray arrayWithContentsOfURL:dataURL]; for(NSString *str in tmpp_array) { [self.array addObject:str]; } [self.tableView performSelectorOnMainThread:@selector(reloadData) withObject:nil waitUntilDone:YES]; }
http://www.cimgf.com/2008/02/16/cocoa-tutorial-nsoperation-and-nsoperationqueue/
Nice Tutorial! It will be better to add a example for how to handle delegate's using this approach.
ReplyDeleteI've used this along with "CFRunLoopRun();" and "CFRunLoopStop(CFRunLoopGetCurrent());" to do that.