This is the 14th day of my participation in the November Gwen Challenge. Check out the event details: The last Gwen Challenge 2021

NSOperation implements multithreaded programming, and the steps are roughly as follows:

  1. Encapsulate the operations to be performed into oneNSOperationIn the object
  2. thenNSOperationObject added toNSOperationQueueIn the
  3. The system automatically puts the operations encapsulated in NSOperation into a new thread for execution

However, NSOperation itself is an abstract class, which can be used in the following ways:

  1. useNSInvocationOperation
  2. useNSBlockOperation
  3. The customNSOperationA subclass of

Easy to use

NSInvocationOperation

NSInvocationOperation *operation = [[NSInvocationOperation alloc] initWithTarget:self selector: @selector(download) object:nil]; // Execute the encapsulated operation [operation start]; -(void)download {NSLog(@"download---- thread id: %@", [NSThreadcurrentThread]); }Copy the code

NSBlockOperation

NSBlockOperation*operation1 = [NSBlockOperation blockOperationWithBlock:^{NSLog(@" here is thread operation1 thread number: %@", [NSThread currentThread]); }]; [operation1 start];Copy the code

According to the printed result, we can find that when the start method is called directly, the system will not open a new thread to execute the task, the task will be executed synchronously in the current thread.

Note: We are talking about the current thread, not the main thread, meaning that if we call operation start on the main thread, the task will be executed on the main thread. But if the start method is called in another child thread, the task is executed in another child thread. Obviously, calling the start method to perform operations is not the original intention of starting threads.

NSOperationQueue use

The combination of NSOperation and NSOperationQueue will maximize the effectiveness of this multi-threaded technology. When NSOperation is added to the NSOperationQueue, the asynchronous operation is automatically performed.

NSOperationQueue *queue = [[NSOperationQueue alloc] init]; NSInvocationOperation *operation = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(download) object:nil]; // Add the operation to the queue [queue addOperation: operation]; - (void)download {NSLog(@"download---- thread id: %@", [NSThread currentThread]); }Copy the code

When an operation is put into a queue, it is automatically executed asynchronously. Download —- Thread Number: {number = 2, name = (null)} Threads are created to execute code asynchronously, so queued operations are often used

Create with block

NSOperationQueue *queue = [[NSOperationQueue alloc] init]; NSBlockOperation *operation = [NSBlockOperation blockOperationWithBlock:^{NSLog(@" %@", [NSThread currentThread]); }]; // Add the operation to the queue [queue addOperation: operation];Copy the code

The following information is displayed: {number = 2, name = (null)}**** From the thread number, you can see that the thread operation is not running in the current thread

Create multiple operations to enqueue

NSOperationQueue *queue = [[NSOperationQueue alloc] init]; NSBlockOperation *operation1 = [NSBlockOperation blockOperationWithBlock:^{NSLog(@" %@", [NSThread currentThread]); }]; NSBlockOperation*operation2 = [NSBlockOperation blockOperationWithBlock:^{NSLog(@" here is thread operation2 thread number: %@", [NSThread currentThread]); }]; NSBlockOperation*operation3 = [NSBlockOperation blockOperationWithBlock:^{NSLog(@" here is thread operation3 thread number: %@", [NSThread currentThread]); }]; // Add the operation to queue [queue addOperation: operation1]; [queue addOperation: operation2]; [queue addOperation: operation3];Copy the code

2021-11-23 17:34:03.282 TTTT [2559:204434] Thread operation 3 Thread number: {number = 4, name = (null)} 2021-11-23 17:34:03.282 TTTT [2559:204432] {number = 3, name = (null)} 2021-11-23 17:34:03.282 TTTT [2559:204433] {number = 2, name = (null)} You can see from the thread number that the thread operation is not running in the current thread

Add multiple subtasks to an operation

NSOperationQueue *queue = [[NSOperationQueue alloc] init]; NSBlockOperation *operation1 = [NSBlockOperation blockOperationWithBlock:^{NSLog(@" %@", [NSThread currentThread]); }]; [operation1 addExecutionBlock:^{NSLog(@" branch number of thread operation1: %@", [NSThread currentThread]);}]; // Add the operation to queue [queue addOperation: operation1];Copy the code

2021-11-23 17:37:28.037 TTTT [2572:207727] Here is the thread operation 1 thread number: {number = 2, name = (null)} 2021-11-23 17:37:28.037 TTTT [2572:207728

As you can see, the operation is automatically split into two threads, and the second thread must start executing after the first thread has finished

—————- But this method of increasing tasks and the above kind of difference code is as follows:

NSOperationQueue *queue = [[NSOperationQueue alloc] init]; NSBlockOperation *operation1 = [NSBlockOperation blockOperationWithBlock:^{NSLog(@" %@", [NSThread currentThread]); }]; [operation1 addExecutionBlock:^{NSLog(@" branch number of thread operation1: %@", [NSThread currentThread]);}]; NSBlockOperation *operation2 = [NSBlockOperation blockOperationWithBlock:^{NSLog(@" here is thread operation2 thread number: %@", [NSThread currentThread]); }]; // Add the operation to queue [queue addOperation: operation1]; [queue addOperation: operation2];Copy the code

2021-11-23 17:41:35.210 TTTT [2587:211052] thread operation 2 thread number: {number = 2, name = (null)} 2021-11-23 17:41:35.210 TTTT [2587:211051] {number = 3, name = (null)} 2:41:35.210 TTTT [2587:211055]}**

As you can see, thread operations 1 and 2 are executed first, and the branch tasks of operation 1 are executed last. There is a clear sequence.

Add thread operations using queues

NSOperationQueue *queue = [[NSOperationQueue alloc] init]; NSBlockOperation *operation1 = [NSBlockOperation blockOperationWithBlock:^{NSLog(@" %@", [NSThread currentThread]); }]; [operation1 addExecutionBlock:^{NSLog(@" branch number of thread operation1: %@", [NSThread currentThread]);}]; NSBlockOperation *operation2 = [NSBlockOperation blockOperationWithBlock:^{NSLog(@" here is thread operation2 thread number: %@", [NSThread currentThread]); }]; // Add the operation to queue [queue addOperation: operation1]; [queue addOperation: operation2]; [queue addOperationWithBlock:^{NSLog(@" here is thread operation 3: %@", [NSThread currentThread]);}];Copy the code

Use queue objects directly to add thread operations.

2021-11-23 18:01:25.354 TTTT [2615:221510] {number = 3, name = (null)} 2021-11-23 18:01:25.354 TTTT [2615:221506] {number = 2, name = (null)} 2021-11-23 18:01:25.354 TTTT [2615:221504] {number = 4, name = (null)} 2021-11-23 18:01:25.354 TTTT [2615:221514]}**

Thread 3 joins the queue directly, but the effect is the same as using Operation

Set the maximum number of concurrent threads

Can be set by maxConcurrentOperationCount maximum number of concurrent threads

NSOperationQueue *queue = [[NSOperationQueue alloc]init]; / / set the maximum number of concurrent queue. MaxConcurrentOperationCount = 2; NSBlockOperation *operation1 = [NSBlockOperation blockOperationWithBlock:^{NSLog(@" %@", [NSThread currentThread]); }]; NSBlockOperation *operation2 = [NSBlockOperation blockOperationWithBlock:^{NSLog(@" here is thread operation2 thread number: %@", [NSThread currentThread]); }]; NSBlockOperation *operation3 = [NSBlockOperation blockOperationWithBlock:^{NSLog(@" here is thread operation3 thread number: %@", [NSThread currentThread]); }]; NSBlockOperation *operation4 = [NSBlockOperation blockOperationWithBlock:^{NSLog(@" here is thread operation4 thread number: %@", [NSThread currentThread]); }]; // Add the operation to queue [queue addOperation: operation1]; [queue addOperation: operation2]; [queue addOperation: operation3]; [queue addOperation: operation4];Copy the code

The following information is displayed:

** 15:20:32.315 TTTT [1443:161764] 0x7FD019D30730 >{number = 3, name = (null)} **2021-11-23 15:20:32.315 TTTT [1443:161765] 0x7fd019f0a290>{number = 2, name = 2021-11-23 15:20:32.316 TTTT [1443:161766] 0x7FD019ea8890 >{number = 5, name = (null)} 2021-11-23 15:20:32.316 TTTT [1443:161767] 0x7fd019d00e10>{number = 4, name = (null)}

Only two threads are started at the same time

That’s where this article ends, and the next one will talk about subclasses of custom NSOperation

reference

  • Reference 1
  • Reference 2