Good articles to my personal technology blog: https://cainluo.github.io/15019481375874.html


Before, we spent a short period of time to GCD to feel the bottom, know GCD operation, I don’t know if you have a good to play with, this time we will talk about iOS multi-threaded operation.

NSOperation, NSOperation is wrapped around GCD, GCD is simple, but it’s C-style code, NSOperation, it’s Objective-C style code, it looks a little bit more iOS, Code to read is also more intuitive, let’s go to see ~

Reprint statement: if you need to reprint this article, please contact the author, and indicate the source, and can not modify this article without authorization.


NSOperation profile

As we mentioned earlier, NSOperation is apple dad’s GCD-based package. The code style is Objective-C, so it is easier to understand and more readable.

But notice that NSOperation needs to be used in conjunction with NSOperationQueue, why?

Because NSOperation alone is a synchronous operation, it does not have the function of starting a new thread, only in conjunction with NSOperationQueue can achieve multi-threaded operations.

We all know that NSOperation is encapsulated in GCD, so it is used just like GCD, where NSOperation is the task in GCD and NSOperationQueue is the queue in GCD.

So using NSOperation requires three steps:

  • Create task: Here we need to drop the executed task toNSOperationIn the
  • Create queue: Create a queueNSOperationQueueQueue object
  • Add a task to the queue: Finally, theNSOperationObject added toNSOperationQueueAnd that’s it.

When used, the NSOperation is automatically removed from the NSOperationQueue and completed in a new thread.


Basic use of NSOperation and NSOperationQueue

One other thing we should know before we start coding is that NSOperation is an abstract class and can’t be used to encapsulate tasks. So what?

There are three ways to implement NSOperation:

  • useNSInvocationOperationSubclasses encapsulate tasks
  • useNSBlockOperationSubclasses encapsulate tasks
  • Use inheritance fromNSOperationSubclass to encapsulate tasks, that is, you can write a custom subclass to encapsulate tasks

As we just learned, NSOperation alone is synchronous execution, so we’ll look at three ways to create it.

NSInvocationOperation

Code up:

- (void)invocationOperation {
    
    NSInvocationOperation *invocationPeration = [[NSInvocationOperation alloc] initWithTarget:self
                                                                                     selector:@selector(runTheOperation)
                                                                                       object:nil];
    
    [invocationPeration start];
}

- (void)runTheOperation {
    
    NSLog(The current thread is: %@[NSThread currentThread]);
}
Copy the code
2017-08-06 00:23:58.611 NSOperation-Example[961:42623] the current thread is <NSThread:0x608000066a00>{number = 1, name = main}
Copy the code

In the result, we can see that when NSOperationQueue is not used, it is executed in the main thread and no new thread is started.

NSBlockOperation

- (void)blockOperation {
    
    NSBlockOperation *blockOperation = [NSBlockOperation blockOperationWithBlock:^{
        
        NSLog(The current thread is: %@[NSThread currentThread]);
    }];
    
    [blockOperation start];
}
Copy the code
2017-08-06 00:26:54.808 NSOperation-Example[1002:47303] the current thread is <NSThread:0x60800006c340>{number = 1, name = main}
Copy the code

In the result, we see that using NSBlockOperation also executes tasks in the main thread and does not start a new thread.

But in NSBlockOperation, we see another method, and what does this method do? Take a look at the code:

- (void)blockOperation {
    
    NSBlockOperation *blockOperation = [NSBlockOperation blockOperationWithBlock:^{
        
        NSLog(The current thread is: %@[NSThread currentThread]);
    }];
    
    [blockOperation addExecutionBlock:^{
        
        NSLog(@" Execute second task, current thread: %@"[NSThread currentThread]);
    }];

    [blockOperation addExecutionBlock:^{
        
        NSLog(@" Execute third task, current thread: %@"[NSThread currentThread]);
    }];

    [blockOperation addExecutionBlock:^{
        
        NSLog(@" Perform the fourth task, current thread: %@"[NSThread currentThread]);
    }];

    [blockOperation start];
}
Copy the code
2017-08-06 00:30:10.238 NSOperation-Example[1043:51425] the current thread is <NSThread:0x60000007bac0>{number = 1, name = main}
2017-08-06 00:30:10.238 NSOperation-Example[1043:51592<NSThread: <NSThread:0x608000267380>{number = 4, name = (null)}
2017-08-06 00:30:10.238 NSOperation-Example[1043:51609] perform the second task, the current thread is: <NSThread:0x600000266c40>{number = 3, name = (null)}
2017-08-06 00:30:10.238 NSOperation-Example[1043:51594] perform the third task, the current thread is: <NSThread:0x608000267200>{number = 5, name = (null)}
Copy the code

From the printed results, we can see that this method can add additional tasks and execute them synchronously in child threads.

Custom NSOperation subclass

So here, we’re going to create a subclass that inherits from NSOperation, and I can’t think of any good scenarios, so I’ll just write them down.

First we create a subclass that inherits from NSOperation and rewrite – (void)main; Methods:

#import "CLOperation.h"

@implementation CLOperation

- (void)main {
    
    for (NSInteger i = 0; i < 5; i++) {
        
        NSLog(@" %zd task executed, current thread: %@", i, [NSThreadcurrentThread]); }}@end
Copy the code

Then go back to the Controller and do something:

- (void)customOperation {
    
    CLOperation *clOperation = [[CLOperation alloc] init];
    
    [clOperation start];
}
Copy the code
2017-08-06 00:37:32.223 NSOperation-Example[1123:59243] performed the no0<NSThread:0x60000006c500>{number = 1, name = main}
2017-08-06 00:37:32.223 NSOperation-Example[1123:59243] performed the no1<NSThread:0x60000006c500>{number = 1, name = main}
2017-08-06 00:37:32.224 NSOperation-Example[1123:59243] performed the no2<NSThread:0x60000006c500>{number = 1, name = main}
2017-08-06 00:37:32.224 NSOperation-Example[1123:59243] performed the no3<NSThread:0x60000006c500>{number = 1, name = main}
2017-08-06 00:37:32.224 NSOperation-Example[1123:59243] performed the no4<NSThread:0x60000006c500>{number = 1, name = main}
Copy the code

The output, as expected, is executed in the main thread and does not start a new thread.


conclusion

In this chapter, we will briefly introduce NSOperation and familiarize ourselves with the basic operations, and then we will use completion in conjunction with NSOperationQueue.


The project address

The address of the project: https://github.com/CainRun/iOS-Project-Example/tree/master/NSOperation-Example


The last