“This is the 11th day of my participation in the Gwen Challenge in November. See details: The Last Gwen Challenge in 2021”

What is the NSOperation

  • NSOperation and NSOperationQueue are multi-threaded solutions provided by Apple. In fact, NSOperation and NSOperationQueue are based on a higher level of ENCAPSULATION of GCD and are fully object-oriented. But it’s easier to use and more readable than GCD

A subclass of NSOperation

NSOperation is an abstract class that does not encapsulate operations. You must use its subclasses, of which there are three

  • NSInvocationOperation
  • NSBlockOperation
  • Custom subclasses inherit NSOperation to implement the corresponding methods internally

About NSInvocationOperation

  • By default, a call to the start method does not open a new thread to perform the operation, but executes the operation synchronously in the current thread

  • The NSInvocationOperation will only be executed asynchronously if it is put into an NSOperationQueue

    Example:

    - (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
    
        NSInvocationOperation *operation1 = [[NSInvocationOperation alloc]initWithTarget:self selector:@selector(run1) object:nil];
        NSInvocationOperation *operation2 = [[NSInvocationOperation alloc]initWithTarget:self selector:@selector(run2) object:nil];
        NSInvocationOperation *operation3 = [[NSInvocationOperation alloc]initWithTarget:self selector:@selector(run3) object:nil];
    
        [operation1 start];
        [operation2 start];
        [operation3 start];
    }
    
    - (void)run1{
        NSLog(@"1 - % @",[NSThread currentThread]);
    }
    
    - (void)run2{
        NSLog(@"2 - % @",[NSThread currentThread]);
    }
    
    - (void)run3{
        NSLog(@"3 - % @",[NSThread currentThread]);
    }
    Copy the code

    The log:


About NSBlockOperation

  • Like NSInvocationOperation, NSBlockOperation simply replaces the method with a block

    Example:

    - (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
    
        NSBlockOperation *operation1 = [NSBlockOperation blockOperationWithBlock:^{
            NSLog(@"1 - % @",[NSThread currentThread]);
        }];
        NSBlockOperation *operation2 = [NSBlockOperation blockOperationWithBlock:^{
            NSLog(@"2 - % @",[NSThread currentThread]);
        }];
        NSBlockOperation *operation3 = [NSBlockOperation blockOperationWithBlock:^{
            NSLog(@"3 - % @",[NSThread currentThread]);
        }];
       
        [operation1 start];
        [operation2 start];
        [operation3 start];
    }
    Copy the code

    The log:

  • NSBlockOperation can add additional operations via addExecutionBlock:. As long as the number of operations encapsulated by NSBlockOperation is greater than 1, it will be executed asynchronously. The additional tasks may not be executed on the child thread, but may also be executed on the main thread.

    Example:

    NSBlockOperation *operation1 = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"1 - % @",[NSThread currentThread]);
    }];
    NSBlockOperation *operation2 = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"2 - % @",[NSThread currentThread]);
    }];
    
    // Add additional tasks
    [operation1 addExecutionBlock:^{
        NSLog(@"3 - % @",[NSThread currentThread]);
    }];
    [operation1 addExecutionBlock:^{
        NSLog(@"4 - % @",[NSThread currentThread]);
    }];
    
    [operation1 start];
    [operation2 start];
    Copy the code

    Log :(execution of 1 and 2 is ordered, but execution of 3 and 4 is concurrent and uncontrollable)


Custom subclasses inherit from NSOperation

  • Using a custom subclass inheriting NSOperation, a call to the start method does not open a new thread to perform the operation, but executes the operation synchronously in the current thread

  • Just override the main method in.m, where the operation is to be performed

    Example:

    // Custom subclasses inherit NSOperation
    #import "Operation.h"
    @implementation Operation
    - (void)main{
        if(! self.isCancelled) { NSLog(@"% @",[NSThread currentThread]);
        }
    }
    @end
    
    / / call
    Operation *operation1 = [[Operation alloc]init];
    [operation1 start];   
    Operation *operation2 = [[Operation alloc]init];
    [operation2 start];
    Copy the code

    The log: