As mentioned in the previous article, nsthread can be used to implement multiple threads, but the developer is responsible for thread creation, maintenance, and exit. When there are many threads, this will be difficult to manage. Nsoperation is an abstract class that encapsulates a task and you cannot instantiate it directly. You can manually manage operation, add it to nsoperationqueue, and add operation to nsoperationqueue. Developers do not need to pay attention to the underlying multi-thread implementation details.
Cocoa provides three different nsoperation methods:
1. nsblockoperation
Block operations allows you to use block objects to execute tasks.
2. nsinvocationoperation
As the name implies, invocation operation provides methods to call common methods to execute tasks. 3. plainoperation inherits from nsoperation and custom nsoperation. During custom nsoperation, at least the main and/or start functions must be rewritten. You must also override isexecuting and isfinished and notify other objects through KVO. You must also specify an initialization function for the custom operation. 2.1 nsblockoperation first comes with the code for Synchronous execution of block operation:
- (BOOL) application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions{NSBlockOperation *simpleOperation = [NSBlockOperation blockOperationWithBlock:^{ NSUInteger counter = 0;for (counter = 0; counter < 1000;counter++){NSLog(@"Count = %lu", (unsigned long)counter); } }];[simpleOperation start];NSLog(@"Main thread is here");return YES;}
The nslog output sequence shows that simpleoperation blocks mainthread and the main thread waits until the block is executed.
Operation is executed by the START method in the thread where it is created by default. We can add simpleoperation to nsoperationqueue to Implement Asynchronous execution, or customize operation and detach a new thread for execution:
Nsoperationqueue * queue = [[nsoperationqueuealloc] init];
[Queue addoperation: simpleoperation];
After you add an operation to the queue, you do not need to manually start it, because the queue will help you, and the queue will manage all the operation added to it. If you want to control it by yourself (this is not recommended), you can use the detach thread method. If multiple operations need to be added, call the function:
-(Void) addoperations :( nsarray *) Ops waituntilfinished :( bool) Wait
At the same time, you can obtain the number of operation and operation in the queue:
-(Nsarray *) operations;
-(Nsuinteger) operationcount;
You can also set the priority for the queue:
-(Nsoperationqueuepriority) queuepriority;
-(Void) setqueuepriority :( nsoperationqueuepriority) P;
Add a name that is easy to remember for the queue:
-(Void) setname :( nsstring *) N;
-(Nsstring *) Name;
Pause queue:
-(Void) setsuincluded :( bool) B;
-(Bool) issuincluded;
2.2 nsinvocationoperation, as its name implies, is to call a method in an nsobject object ). Similarly, let's take a look at the synchronization execution: Self. simpleoperation = [[nsinvocationoperation alloc] initwithtarget: Self selector: @ selector (simpleoperationentry :) object: simpleobject]; [self. simpleoperation start];
In this way, simpleoperation will be executed in the current thread that creates it (generally main thread), and its execution will block the current thread. Of course, this does not have much practical significance, but if we add simpleoperation to the queue, it can be executed in parallel with the current thread to improve efficiency.
NSNumber *firstNumber = [NSNumber numberWithInteger:111]; NSNumber *secondNumber = [NSNumber numberWithInteger:222];self.firstOperation =[[NSInvocationOperation alloc] initWithTarget:selfselector:@selector(firstOperationEntry:) object:firstNumber];//firstself.secondOperation = [[NSInvocationOperation alloc] initWithTarget:selfselector:@selector(secondOperationEntry:) object:secondNumber];//secondself.operationQueue = [[NSOperationQueue alloc] init];/* Add the operations to the queue */ [self.operationQueue addOperation:self.firstOperation];[self.operationQueue addOperation:self.secondOperation];
In the above Code, both operations are executed in parallel with the main thread in their respective threads, and the two operations are also executed in parallel. In the queue, you can get and set the maximum number of parallel operation:
-(Nsinteger) maxconcurrentoperationcount;
-(Void) setmaxconcurrentoperationcount :( nsinteger) CNT;
So what if I want secondoperation to be executed after firstoperation? That is to say, secondoperation will not begin until the execution of firstoperation is complete. One operation can depend on one or more operations, that is, it can be executed after the dependent operation is completed. If you do not add dependencies for an operation, you have no control over when to execute the dependency. Adddependency: This method can solve this problem by adding dependency attributes for two operations before being added to the queue.
[Self. secondoperation adddependency: Self. firstoperation];
Call removedependency to cancel dependency when dependency is no longer needed.
[Self. secondoperation removedependency: Self. firstoperation];
In addition, nsinvocationoperation can also be initialized with the specified initialization function:
-(ID) initwithinvocation :( nsinvocation *) inv; // designated initializer
2.3 operation other notes a operation has a corresponding status to identify its execution process.
-(Bool) iscancelled;
-(Bool) isexecuting;
-(Bool) isfinished;
-(Bool) isconcurrent;
-(Bool) isready;
You can cancel an operation by using-(void) Cancel.
In the queue, cancel all operations through-(void) cancelalloperations.