Summary of basic principles of iOS
GCD, Grand Central Dispatch, is a C-based function that automatically takes advantage of more CPU cores and automatically manages thread life cycles
Summary: GCD is a function that adds a task to a queue and specifies its execution
function
There are two ways to perform tasks in GCD: synchronous function (dispatch_sync) and asynchronous function (dispatch_async).
Synchronization function (dispatch_sync)
Have to wait for
The next statement is executed only after the current statement completes, blocking the current threadNo new threads are created
Asynchronous functions (dispatch_async)
Don't have to wait for
When the current statement completes, the next statement can be executed- with
The ability to initiate new threads
, but not necessarily new threads, depending on the queue type specified by the current task
The queue
Dispatch queue is a kind of data structure, a special linear table, which is used to store the queue of tasks. In accordance with THE FIFO (first-in, first-out) principle, new tasks are always inserted to the end of the queue. Tasks are read from the front of the queue.
Serial queues
Only one task can be performed at a time
dispatch_queue_create("xxx", DISPATCH_QUEUE_SERIAL);
Creating a serial queueDISPATCH_QUEUE_SERIAL
You can also useNULL
Instead of
Dispatch_queue_t serialQueue1 = dispatch_queue_create(" com.cjl.queue ", NULL); dispatch_queue_t serialQueue2 = dispatch_queue_create("com.CJL.Queue", DISPATCH_QUEUE_SERIAL);Copy the code
Concurrent queue
Multiple tasks can be performed at the same time
dispatch_queue_create("xxx", DISPATCH_QUEUE_CONCURRENT);
Creating concurrent queues- Only in the
An asynchronous function
Only under the concurrent effect
Dispatch_queue_t concurrentQueue = dispatch_queue_create(" com.cjl.queue ", DISPATCH_QUEUE_CONCURRENT);Copy the code
The home side column
Main Dispatch Queue
- special
Serial queues
- Dedicated to the
A serial queue that schedules tasks on the main thread
, depends on the main program, the main Runloop, inThe main function
Before the call dispatch_get_main_queue()
Gets the main queue
Dispatch_queue_t mainQueue = dispatch_get_main_queue();Copy the code
Global queue
Global Dispatch Queue
-
The GCD default concurrency queue
-
dispatch_get_global_queue(intptr_t identifier, uintptr_t flags); Gets the global concurrent queue
- The first parameter says
Queue priority
, the defaultDISPATCH_QUEUE_PRIORITY_DEFAULT=0
After iOS9.0 was quality of servicequality-of-service
replace - The second argument uses 0
- The first parameter says
Dispatch_queue_t globalQueue = dispatch_get_global_queue(0, 0); -dispatch_queue_priority_high -- QOS_CLASS_USER_INITIATED - DISPATCH_QUEUE_PRIORITY_DEFAULT -- QOS_CLASS_DEFAULT - DISPATCH_QUEUE_PRIORITY_LOW -- QOS_CLASS_UTILITY - DISPATCH_QUEUE_PRIORITY_BACKGROUND -- QOS_CLASS_BACKGROUNDCopy the code
In daily development, global queue + concurrent juxtaposition is usually used in this way
Dispatch_async (dispatch_get_global_queue(0, 0)) ^{dispatch_async(dispatch_get_main_queue(), ^{// return to main thread for UI}); });Copy the code
Serial queue + synchronization function
[Sequential execution of tasks] : Tasks are executed one after the other in the current thread without creating a new thread
Serial queue + asynchronous function
[Sequential execution of tasks] : Tasks are executed one after another, creating a new thread
Concurrent queue + synchronization function
[Sequential execution of tasks] : Tasks are executed one after another without opening up threads
Concurrent queue + asynchronous function
[Out-of-order execution of tasks] : Tasks are executed out of order, and new threads are created
Main queue + synchronization function
[Cause deadlock] : Tasks wait for each other, causing deadlock
Deadlock phenomenon
- The main thread is waiting to execute the task first because of your synchronization function
- The main queue waits for the main thread to complete before executing its own task
- Main queue and main thread waiting on each other cause deadlock
Main queue + asynchronous function
[Sequential execution of tasks] : Tasks are executed one after another without opening up threads
Global concurrent queue + synchronization function
[Sequential execution of tasks] : Tasks are executed one after another without opening new threads
Global concurrent queue + asynchronous function
[Task out of order] : When a task is out of order, a new thread will be created
conclusion
Function \ queue | Serial queues | Concurrent queue | The home side column | Global concurrent queue |
---|---|---|---|---|
Synchronization function | Execute sequentially without opening up threads | Execute sequentially without opening up threads | A deadlock | Execute sequentially without opening up threads |
An asynchronous function | Sequential execution opens up threads | Out of order execution, open up threads | Execute sequentially without opening up threads | Out of order execution, open up threads |
Related interview questions
[Interview question 1] Asynchronous function + concurrent queue
- (void)interview01{dispatch_queue_t queue = dispatch_queue_create(" com.cjl.queue ", DISPATCH_QUEUE_CONCURRENT); NSLog(@"1"); Dispatch_async (queue, ^{NSLog(@"2"); dispatch_async(queue, ^{ NSLog(@"3"); }); NSLog(@"4"); }); NSLog(@"5"); } ---------- ----------- the output sequence is 1 5 2 4 3Copy the code
An asynchronous function opens a new thread, does not block the main queue,
Analysis of the
- The mission of the main line is
NSLog(1), asynchronous Block, NSLog(5)
Because theNSLog(1)
andNSLog(5)
Is the same, andAsynchronous Block
Is more complex, soNSLog (1) and the NSLog (5)
Prior to theAsynchronous Block
- in
Asynchronous Block
By the same token,NSLog (2) and the NSLog (4)
Prior to theAsynchronous Block
. - in
Main thread blocking
Or in other extreme cases,NSLog(2)
Have priorityNSLog(1)
andNSLog(5)
[Interview question 2] Asynchronous function nested synchronous function + concurrent queue
- (void)interview02{dispatch_queue_t queue = dispatch_queue_create(" com.cjl.queue ", DISPATCH_QUEUE_CONCURRENT); NSLog(@"1"); // dispatch_async(queue, ^{NSLog(@"2")); // dispatch_sync(queue, ^{NSLog(@"3"); }); NSLog(@"4"); }); NSLog(@"5"); } ---------- ----------- the output sequence is 1 5 2 3 4Copy the code
Analysis of the
- The analysis of task 1 and task 5 is the same as the previous interview, so the order of execution is
Task 1. Task 5. Asynchronous block
- Task 2 is executed first in an asynchronous block, because the synchronous function will
Blocking threads
, so the execution order isTask 2, Task 3, task 4
Asynchronous serial nesting Synchronous serial nesting
- (void)interview03{dispatch_queue_t queue = dispatch_queue_create(" com.cjl.queue ", NULL); NSLog(@"1"); // dispatch_async(queue, ^{NSLog(@"2")); // dispatch_sync(queue, ^{NSLog(@"3"); }); NSLog(@"4"); }); NSLog(@"5"); } ---------- ----------- is displayed in the following order: 1 5 2 Deadlock crashCopy the code
Analysis of the
Task 1. Task 5. Asynchronous block
The order of execution is the same as analyzed above- in
Asynchronous block
In, first willTask 2
,The synchronization block
,Task 4
Add to serial queue, wait to execute, serial queue in order of tasksTask 2 --> Synchronize block --> Task 4
. - To start the execution, run it first
Task 2
And then to performThe synchronization Block
, because it is the same serial queue, will beTask 3
Add inTask 4
After, the sequence of tasks in the serial queueSynchronize block 4 --> Task 3
. - Because the synchronization function will
Blocking the current thread
, soTask 4
Waiting for theThe synchronization block
Execution completed, but now againSerial queues
First in, first out, soTask 3
Waiting for theTask 4
, resulting inA deadlock
A deadlock
There is a key stack of information_dispatch_sync_f_slow
Asynchronous function + synchronous function + concurrent queue
What is the order in which the following code is executed? A: 1230789 B: 1237890 C: 3120798 D: 2137890
- (void)interview04{dispatch_queue_t queue = dispatch_queue_create(" com.cjl. queue ", DISPATCH_QUEUE_CONCURRENT); Dispatch_async (queue, ^{NSLog(@"1"); }); dispatch_async(queue, ^{ NSLog(@"2"); }); Dispatch_sync (queue, ^{NSLog(@"3"); }); NSLog(@"0"); dispatch_async(queue, ^{ NSLog(@"7"); }); dispatch_async(queue, ^{ NSLog(@"8"); }); dispatch_async(queue, ^{ NSLog(@"9"); }); } ---------- prints the result ----------- in the order of :(1, 2, 3 out of order) 0 (7, 8, 9 out of order), it can be determined that 0 must be after 3, before 789Copy the code
Analysis of the
- because
Task 1, Task 2
It’s asynchronous concurrency, it opens up new threads, so there’s no fixed order, - In the same way,
Task 7, task 8, task 9
There is no set order - because
Task 3
It’s synchronous concurrency, which blocks the current thread, soTask 3
inTask 0
It was executed before, soTask 0
Will be inTask 3
After that,Task 7, 8, 9
before
There are several types of queues below
- Serial Dispatch Queue dispatch_queue_t serialQueue = dispatch_queue_create(" com.cjl.queue ", NULL); -concurrent Dispatch Queue dispatch_queue_t concurrentQueue = dispatch_queue_create(" com.cjl.queue ", DISPATCH_QUEUE_CONCURRENT); -dispatch Queue dispatch_queue_t mainQueue = dispatch_get_main_queue(); -global Dispatch Queue dispatch_queue_t globalQueue = dispatch_get_global_queue(0, 0);Copy the code
There are only two types of queues:
- Concurrent queue:
Concurrent queue (DISPATCH_QUEUE_CONCURRENT)
,Global concurrent queue (dispatch_get_global_queue)
- Serial queue:
Serial queue (DISPATCH_QUEUE_SERIAL \ NULL)
,Serial main queue (dispatch_get_main_queue)