The iOS queue in the iOS application controls the method of thread execution through the dispatch queue

  • 2020-06-01 11:04:33
  • OfStack

The core of GCD programming is the dispatch queue. The execution of dispatch block will eventually be put into a queue. It is similar to NSOperationQueue but more complex and powerful, and can be used nested. Therefore, combining with GCD implemented by block, the feature of function closure (Closure) is brought into full play.

The dispatch queue can be generated in several ways:

1. dispatch_queue_t queue = dispatch_queue_create(" com.dispatch.serial ", DISPATCH_QUEUE_SERIAL); // generate a serial queue in which block is executed in first-in, first-out (FIFO) order, in effect single-threaded. The first parameter is the name of the queue, which is useful when debugging your application, so try not to duplicate it.

2. dispatch_queue_t queue = dispatch_queue_create(" com.dispatch.concurrent ", DISPATCH_QUEUE_CONCURRENT); // generate a concurrent execution queue and block is distributed to multiple threads for execution

3. dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); // get the concurrent queue generated by the program process by default. The priority can be set to select the high, medium and low priority queues. Because it is generated by default, dispatch_resume() and dispatch_suspend() cannot be called to control execution continuation or interruption. It is important to note that three queues do not represent three threads, and there may be more threads. The concurrent queue can automatically generate a reasonable number of threads according to the actual situation, which can also be understood as the dispatch queue realizes the management of a thread pool and is transparent to the program logic.

The official website explains that there are three concurrent queues, but there is actually one queue with a lower priority, with a priority of DISPATCH_QUEUE_PRIORITY_BACKGROUND. When debugging Xcode, you can observe the various dispatch queues in use.

4. dispatch_queue_t queue = dispatch_get_main_queue(); // get the dispatch queue of the main thread, which is actually a serial queue. There is also no control over whether the execution of the main dispatch queue continues or is interrupted.

Threading example
To make it easier to use GCD, apple has provided a few ways to make it easier to execute block on the main thread or background thread, or to delay execution. The examples used are as follows:


 //  Background execution:
 dispatch_async(dispatch_get_global_queue(0, 0), ^{
      // something
 });


 // Main thread execution:
 dispatch_async(dispatch_get_main_queue(), ^{
      // something
 });


 // 1 Secondary execution:
 static dispatch_once_t onceToken;
 dispatch_once(&onceToken, ^{
     // code to be executed once
 });


 // delay 2 Seconds to perform:
 double delayInSeconds = 2.0;
 dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, delayInSeconds * NSEC_PER_SEC);
 dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
     // code to be executed on the main queue after delay
 });

dispatch_queue_t can also be defined by itself. If you want to customize queue, you can use the dispatch_queue_create method, for example:

 // The custom dispatch_queue_t
 dispatch_queue_t urls_queue = dispatch_queue_create("blog.devtang.com", NULL);
 dispatch_async(urls_queue, ^{ 
   // your code
 });
 dispatch_release(urls_queue);

In addition, GCD has some advanced USES, such as having two threads execute in parallel in the background, and then summarizing the results when both threads have finished. This can be implemented with dispatch_group_t, dispatch_group_async, dispatch_group_notify, as shown below:

 // Combined results
 dispatch_group_t group = dispatch_group_create();
 dispatch_group_async(group, dispatch_get_global_queue(0,0), ^{
      // Threads that execute in parallel 1
 });
 dispatch_group_async(group, dispatch_get_global_queue(0,0), ^{
      // Threads that execute in parallel 2
 });
 dispatch_group_notify(group, dispatch_get_global_queue(0,0), ^{
      // Summary results
 });

The dispatch queue does not support cancel (cancel) and does not implement the dispatch_cancel() function, unlike NSOperationQueue, which is a minor drawback.


Related articles: