Multithreading is an important aspect of iOS applications. We cannot always load our main thread with all the tasks. If an application is designed to perform all the tasks serially then there is no need of multithreading, but most of the applications have some tasks which can be completed without depending on other tasks, or if main thread has to be left available for user interaction. In these cases, it's a compulsion to go for multithreading.
You can always go with NSThread to multithread your application, but doing so is only recommended when your requirements are such that there is no other option, except to use NSThread. Sometimes using NSThread may not be as efficient as using NSOperation, as NSOperation takes into account the current system load and cores available to decide the extent to which application can be multithreaded.
If you use NSOperation, you don't have to take care of spawning a new thread or terminating it after your work is complete. You also don't have to worry about the number of threads to use to make application work more efficiently. It's not like, using more threads makes your application more efficient. Remember, a thread always has a cost associated with it, as it shares stack space with the main process.
In simple terms, any instance of subclass of NSOperation class will denote the operation which we have to perform in mutithreaded manner with respect to other operations denoted by other instances of subclass of NSOperation or the operation performed by main thread itself.
Why have I used term, subclass of NSOperation class?
NSOperation is an abstract class, so you cannot instantiate it directly. You will have to subclass it if you have to use it. But don't worry, Foundation framework provides NSInvocationOperation subclass which can be used directly for instantiating operations.
NSInvocationOperation provides almost everything to perform multithreading, but in case if you feel that it is unable to cater your needs, you can always subclass NSOperation.
NSOperationQueue class can be instantiated directly to create a queue where we can add our operations. Once you add operations to NSOperationQueue, it will take care of when and how to execute your operations, and how many threads to use for execution. NSOperationQueue starts executing operations almost as soon as they are added to the queue, provided they do not have dependency on some other operations in the same or some other queue, or your queue is not overloaded.
Now, let's see how to use NSOperation and NSOperationQueue.
Note: I won't be dealing with creating custom subclass of NSOperation in this post.
Create an operation
@implementation testViewController
- (void)viewDidLoad {
aQueue = [[NSOperationQueue alloc] init];
[super viewDidLoad];
}
-(void)fun1:(NSObject *)obj
{
NSInvocationOperation* theOp = [[NSInvocationOperation alloc] initWithTarget:self
selector:@selector(fun2:) object:obj];
[theOp addObserver:self forKeyPath:@"isFinished" options:NSKeyValueObservingOptionNew |
NSKeyValueObservingOptionOld context:NULL];
[aQueue addOperation:theOp];
[theOp release];
}
-(void)fun2:(NSObject *) obj
{
// Start your parallel task
}
- (void)observeValueForKeyPath:(NSString *)keyPath
ofObject:(id)object
change:(NSDictionary *)change
context:(void *)context {
if ([keyPath isEqual:@"isFinished"]) {
// Do something, operation has finished.
}
@end
fun2 is the entry point for the new task/thread. NSOperation is KVO (Key Value Observing) compliant class, so you can register your objects for receiving notifications. In the above code, I have registered the current object for receiving notification when an operation finishes.
Note: Don't try to change your operation object once it has been submitted to the queue, because after submitting you never know when queue starts executing it.
For more info visit
No comments:
Post a Comment