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:
- Encapsulate the operations to be performed into one
NSOperation
In the object - then
NSOperation
Object added toNSOperationQueue
In the - 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:
- use
NSInvocationOperation
- use
NSBlockOperation
- The custom
NSOperation
A 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