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


In the previous article, we got a general idea of what GCD is, and how to create queues and tasks, but the previous ideas are just ideas. I think there are a lot of people who don’t like it, and they are going to start to shout at me. This is where we put the code into practice. Take a look at GCD development in iOS.

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.


Basic use of CGD

Here we need to create a project and test the waters:

Parallel queue + synchronous execution

- (void)syncQueueConcurrent {
    
    NSLog(@" Start the mission");
    
    dispatch_queue_t queue = dispatch_queue_create("test", DISPATCH_QUEUE_CONCURRENT);
    
    dispatch_sync(queue, ^{
        
        NSLog(The current thread of the first task is: %@[NSThread currentThread]);
    });
    
    dispatch_sync(queue, ^{
        
        NSLog(The current thread of the second task is: %@[NSThread currentThread]);
    });

    dispatch_sync(queue, ^{
        
        NSLog(The current thread of the third task is: %@[NSThread currentThread]);
    });
    
    NSLog(@" End the mission");
}
Copy the code
2017-08-05 15:03:55.567 GCD-Example[14007:7612071] Start the task2017-08-05 15:03:55.567 GCD-Example[14007:7612071<NSThread:0x608000067340>{number = 1, name = main}
2017-08-05 15:03:55.567 GCD-Example[14007:7612071<NSThread:0x608000067340>{number = 1, name = main}
2017-08-05 15:03:55.568 GCD-Example[14007:7612071<NSThread:0x608000067340>{number = 1, name = main}
2017-08-05 15:03:55.568 GCD-Example[14007:7612071] End The taskCopy the code
  • From the output, we can see that the current thread is now the same thread namedmainAnd the number of threads is only1.
  • I added one before and after the missionLogFrom the order of execution, we can know thatParallel queue + synchronous executionIt’s done task by task.

Parallel queue + asynchronous execution

Let’s look at the combination of parallel queue + asynchronous execution:

- (void)asyncQueueConcurrent {
    
    NSLog(@" Start the mission");
    
    dispatch_queue_t queue = dispatch_queue_create("test", DISPATCH_QUEUE_CONCURRENT);
    
    dispatch_async(queue, ^{
        
        NSLog(The current thread of the first task is: %@[NSThread currentThread]);
    });
    
    dispatch_async(queue, ^{
        
        NSLog(The current thread of the second task is: %@[NSThread currentThread]);
    });
    
    dispatch_async(queue, ^{
        
        NSLog(The current thread of the third task is: %@[NSThread currentThread]);
    });
    
    NSLog(@" End the mission");
}
Copy the code
2017-08-05 15:08:40.069 GCD-Example[14052:7619255] Start the task2017-08-05 15:08:40.070 GCD-Example[14052:7619255] End The task2017-08-05 15:08:40.070 GCD-Example[14052:7619380<NSThread:0x60800026a640>{number = 5, name = (null)}
2017-08-05 15:08:40.070 GCD-Example[14052:7619363<NSThread:0x60800026a5c0>{number = 3, name = (null)}
2017-08-05 15:08:40.070 GCD-Example[14052:7619362<NSThread:0x60000026bb00>{number = 4, name = (null)}
Copy the code
  • From the output, we can see that there are several threads, and the name of the thread is not known, and from the time, we can see that the task is executed almost at the same time.
  • So we can get a result,Parallel queue + asynchronous executionIn addition to the combinationThe home side columnTo execute the task, it also opens several additional threads to execute the task in parallel.

Serial queue + synchronous execution

Continue with the next serial queue + synchronous execution combination:

- (void)syncQueueSerial {
    
    NSLog(@"Start the mission.");

    dispatch_queue_t queue = dispatch_queue_create("test", DISPATCH_QUEUE_SERIAL);
    
    dispatch_sync(queue, ^{
        
        NSLog(@"The current thread of the first task is: %@", [NSThread currentThread]);
    });
    
    dispatch_sync(queue, ^{
        
        NSLog(@"The second task is currently thread: %@", [NSThread currentThread]);
    });
    
    dispatch_sync(queue, ^{
        
        NSLog(@"The third task is currently thread: %@", [NSThread currentThread]);
    });
    
    NSLog(@"End of mission.");
}
Copy the code
2017-08-05 15:16:21.723 GCD-Example[14119:7628753] Start the task2017-08-05 15:16:21.723 GCD-Example[14119:7628753<NSThread:0x6080000794c0>{number = 1, name = main}
2017-08-05 15:16:21.724 GCD-Example[14119:7628753<NSThread:0x6080000794c0>{number = 1, name = main}
2017-08-05 15:16:21.724 GCD-Example[14119:7628753<NSThread:0x6080000794c0>{number = 1, name = main}
2017-08-05 15:16:21.724 GCD-Example[14119:7628753] End The taskCopy the code
  • And judging by the results, thisSerial queue + synchronous executionComposition is performed one task at a time, in the main queue, without starting a new thread.
  • Since it’s a serial queue, we can see above that the first start is executedLogAnd then the tasks are added one by one, and finally at the end of executionLog.

Serial queue + asynchronous execution

Continue serial queue + asynchronous execution:

- (void)asyncQueueSerial {
    
    NSLog(@" Start the mission");
    
    dispatch_queue_t queue = dispatch_queue_create("test", DISPATCH_QUEUE_SERIAL);
    
    dispatch_async(queue, ^{
        
        NSLog(The current thread of the first task is: %@[NSThread currentThread]);
    });
    
    dispatch_async(queue, ^{
        
        NSLog(The current thread of the second task is: %@[NSThread currentThread]);
    });
    
    dispatch_async(queue, ^{
        
        NSLog(The current thread of the third task is: %@[NSThread currentThread]);
    });
    
    NSLog(@" End the mission");
}
Copy the code
2017-08-05 17:32:06.723 GCD-Example[14279:7669095] Start the task2017-08-05 17:32:06.723 GCD-Example[14279:7669095] End The task2017-08-05 17:32:06.723 GCD-Example[14279:7669192<NSThread:0x60800006ee00>{number = 3, name = (null)}
2017-08-05 17:32:06.724 GCD-Example[14279:7669192<NSThread:0x60800006ee00>{number = 3, name = (null)}
2017-08-05 17:32:06.724 GCD-Example[14279:7669192<NSThread:0x60800006ee00>{number = 3, name = (null)}
Copy the code
  • From the result, we can see that a new thread is started to execute the task, but since isSerial queuesSo the tasks here are executed one after another.
  • Another point here is that we can see the development printed firstLogAnd the endLogThe task is not executed all at once. The task is added to the queue and then executed synchronously.

The home side column

The main queue is a special queue that comes with the GCD. There are two things to note here:

  • All inThe home side columnAll the tasks performed in theThe main threadIn the execution.
  • We can get throughdispatch_get_main_queue()Gets the main queue.

Instead of saying so much, it’s better to write some code:

Main queue + synchronous execution

- (void)syncMainQueue {
    
    NSLog(@" Start the mission");
    
    dispatch_queue_t queue = dispatch_get_main_queue();
    
    dispatch_sync(queue, ^{
        
        NSLog(The current thread of the first task is: %@[NSThread currentThread]);
    });
    
    dispatch_sync(queue, ^{
        
        NSLog(The current thread of the second task is: %@[NSThread currentThread]);
    });
    
    dispatch_sync(queue, ^{
        
        NSLog(The current thread of the third task is: %@[NSThread currentThread]);
    });
    
    NSLog(@" End the mission");
}
Copy the code
2017-08-05 17:56:24.607 GCD-Example[14437:7689741] Start the taskCopy the code

When we run, we find an exception. The assertion does not move after executing the Log. Why?

It’s actually because we’re doing self syncMainQueue in ViewDidload; Method, as we all know, synchronous execution is performed task by task.

But the main line is still executing [self syncMainQueue]; “, we plug tasks into the main thread again, this time there will be an exception, we call stuck thread.

In order to solve this problem, we need to improve the solution in ViewDidload:

- (void)viewDidLoad {
    [super viewDidLoad];
    
    dispatch_queue_t queue = dispatch_queue_create("test", DISPATCH_QUEUE_CONCURRENT);
    
    dispatch_async(queue, ^{
        
        [self syncMainQueue];
    });
}
Copy the code
2017-08-05 18:03:33.209 GCD-Example[14492:7698292] Start the task2017-08-05 18:03:33.214 GCD-Example[14492:7698172<NSThread:0x600000066340>{number = 1, name = main}
2017-08-05 18:03:33.215 GCD-Example[14492:7698172<NSThread:0x600000066340>{number = 1, name = main}
2017-08-05 18:03:33.216 GCD-Example[14492:7698172<NSThread:0x600000066340>{number = 1, name = main}
2017-08-05 18:03:33.216 GCD-Example[14492:7698292] End The taskCopy the code

Well, the transformation can successfully complete the task, here also need to mention two more points:

  • In the execution of the results, although we areViewDidloadUsing aParallel + asynchronousThis will not affect the execution order of tasks in the main queue, nor will it start new threads.
  • The main queue is a serial queue, so we can see that tasks are executed one after another.

Main queue + asynchronous execution

The final combination of main queue + asynchronous execution:

- (void)asyncMainQueue {
    
    NSLog(@" Start the mission");
    
    dispatch_queue_t queue = dispatch_get_main_queue();
    
    dispatch_async(queue, ^{
        
        NSLog(The current thread of the first task is: %@[NSThread currentThread]);
    });
    
    dispatch_async(queue, ^{
        
        NSLog(The current thread of the second task is: %@[NSThread currentThread]);
    });
    
    dispatch_async(queue, ^{
        
        NSLog(The current thread of the third task is: %@[NSThread currentThread]);
    });
    
    NSLog(@" End the mission");
}
Copy the code
2017-08-05 18:08:16.059 GCD-Example[14537:7704614] Start the task2017-08-05 18:08:16.059 GCD-Example[14537:7704614] End The task2017-08-05 18:08:16.064 GCD-Example[14537:7704614<NSThread:0x608000261700>{number = 1, name = main}
2017-08-05 18:08:16.064 GCD-Example[14537:7704614<NSThread:0x608000261700>{number = 1, name = main}
2017-08-05 18:08:16.065 GCD-Example[14537:7704614<NSThread:0x608000261700>{number = 1, name = main}
Copy the code
  • And we can see from the results, even though we’re using PIAsynchronous execution, has the ability to start new threads, but since this is the main queue, all tasks are in the main thread and are executed one after another.
  • In addition, we can see that execution starts firstLogEnd,Log, and then execute the tasks in the main queue. This shows that the tasks are not executed immediately, but after all tasks are added to the queue.

conclusion

After learning, we can happily play with GCD, queue, task and so on, don’t have to worry about any more.


The project address

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


The last