Complete explanation of the GCD series (1) dispatch_async; dispatch_sync; dispatch_async_f; dispatch_sync_f, dispatchasync
Why do we need to write this series? Baidu has found many one-sided blogs, copied them, and written them roughly.
Therefore, I want to write this series and try to fully express the powerful functions of GCD in the official website documents. It is convenient for you and others. If you find any problems, please submit them.
The plan of this tutorial: after reading the official GCD documents, I cannot figure out how to write so many functions in detail in a single article.
Therefore, I decided to open a column to write this tutorial. Plan 8 articles to introduce various features, each with simple and complete sample code. Last
This article summarizes the classic use cases of GCD. The source code only supports the Swift version. It is planned to be completed within one month because I have to go to work. Two articles per week.
Original Blog, reprinted, please indicate the source
This column address
Http://blog.csdn.net/column/details/swift-gcd.html
GCD
Grand Central Dispatch
Introduction: GCD is a complete package for multi-thread and multi-core development. When using GCD, the system will automatically schedule according to CPU usage, so GCD is
A simple and easy-to-use multi-threaded Multi-core development tool with good results.
Note:
1. Use the fork () function with caution (it is not very clear that the process should not be used)
2. GCD is a C-language API, so exceptions are not caught. The exception should be handled before a task submitted to GCD is completed.
Tutorial 1
Tutorial 1 covers
1. Four priorities of GCD global queue
2. Several types of GCD used in this article
3. dispatch_async/dispatch_async_f
4. dispatch_sync/dispatch_sync_f
I. Concepts and types
For GCD, all the executions are placed in the queue, which features FIFO (first-submitted, first-executed ).
GCD queues include main, global, and create queues)
For global queues, there are four by default, which are divided into four priorities.
#define DISPATCH_QUEUE_PRIORITY_HIGH 2#define DISPATCH_QUEUE_PRIORITY_DEFAULT 0#define DISPATCH_QUEUE_PRIORITY_LOW (-2)#define DISPATCH_QUEUE_PRIORITY_BACKGROUND INT16_MIN
DISPATCH_QUEUE_PRIORITY_HIGH: The highest priority. It is executed before default and low.
DISPATCH_QUEUE_PRIORITY_DEFAULT default priority. Before low, after high
DISPATCH_QUEUE_PRIORITY_LOW is executed after high and default
DISPATCH_QUEUE_PRIORITY_BACKGROUND: The task submitted to this queue is executed after the high-priority task and the task submitted to the background queue are executed. Official documentation: (the queue is scheduled for execution after all high priority queues have been scheduled and the system runs items on a thread whose priority is set for background status .)
Several types used
Typealias dispatch_queue_t = NSObject // lightweight queue typealias dispatch_block_t = ()-> Void // closure of queue execution (block in Objective C)
Several Concepts
Tasks submitted asynchronously return immediately and are executed in the backend queue.
After the synchronization task is completed
Parallel Execution (Global Queue) refers to a task submitted to a queue. For example, if Task 1 and Task 2 are submitted, the task starts to be executed at Task 1 and is not completed, task 2 can be started.
Serial execution (the user creates a queue) submits tasks to a queue. For example, if Task 1 and Task 2 are submitted, Task 2 can be executed only after Task 1 is completed.
Note: whether a task submitted to the queue is executed in serial or in parallel is determined by the queue itself.
Ii. Detailed examples
func dispatch_async(_ queue: dispatch_queue_t!, _ block: dispatch_block_t!)
Parameters:
The queue submitted by the queue. The queue type determines whether it is a serial task or a task in the parallel execution queue.
Closure of block execution
func dispatch_async_f(_ queue: dispatch_queue_t!, _ context: UnsafeMutablePointer<Void>, _ work: dispatch_function_t)
Parameters
The queue submitted by the queue. The queue type determines whether it is a serial task or a task in the parallel execution queue.
Parameters passed by context to work
Functions executed by work (C functions)
The parameters of dispatch_sync and dispatch_sync are the same as those above, so they are not listed.
In general, a suffix of _ f (such as dispatch_sync_f and dispatch_after_f) is used to submit a C function to the queue, because this form is rarely used. Here is only a simple example, the values involved in _ f are skipped.
1. dispatch_async/dispatch_sync
Function: Submit to the queue for asynchronous/Synchronous execution.
In this example, download an image and notify the UI to change after the image is downloaded.
Note: to change the UI, it must be executed on the main queue column.
Here we use a function to obtain the global queue.
func dispatch_get_global_queue(_ identifier: Int, _ flags: UInt) -> dispatch_queue_t!
The first parameter of this function is the queue priority, and the second parameter is meaningless. You can simply enter 0.
Create a single-page-based Swift project, and then in ViewController. swift,
class ViewController: UIViewController{ var imageview = UIImageView(frame: CGRectMake(40,40,200,200)) override func viewDidLoad(){ super.viewDidLoad() imageview.contentMode = UIViewContentMode.ScaleAspectFit self.view.addSubview(imageview) let url = "http://f.hiphotos.baidu.com/image/pic/item/e1fe9925bc315c60191d32308fb1cb1348547760.jpg" let imageURL = NSURL(string:url) var globalQueueDefault = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0)dispatch_async(globalQueueDefault){var imageData = NSData(contentsOfURL:imageURL!)var image = UIImage(data:imageData!)if let successfulImage = image{sleep(2)dispatch_async(dispatch_get_main_queue()){self.imageview.image = successfulImage}}} } override func didReceiveMemoryWarning(){ super.didReceiveMemoryWarning() } } Run the command and observe the effect: view is loaded immediately. After a while, the image is downloaded and the UI changes.
Then, observe dispatch_sync.
You only need to modify this line.
dispatch_sync(globalQueueDefault,0){
Run the command and observe the effect: view loading is slow, but the image is downloaded when loading. The UI has changed. You can click a breakpoint on this line to find that the asynchronous execution will return immediately, and the synchronous execution will wait until the execution ends and return.
Therefore, when we put a very time-consuming task in the background queue and wait for the notification UI to change, the UI will not be blocked and the user experience will be reduced.
2. dispatch_async_f/dispatch_sync_f
A simple instance submits a C function to the queue
First, create a single page-based swift project named testForCSDN, and then create a new C language file named hwcText-> click include header file-> click include Bridging-Header.h
In this way, three files are added to the project.
HwcTest. c
HwcTest. h
TestForCSDN-Bridging-Header.h
Complete code
TestForCSDN-Bridging-Header.h
#import "hwcTest.h"
HwcTest. h
#include <stdio.h>#include <unistd.h>typedef void (*hwcTestForGCD)(void*);hwcTestForGCD getFuncPointer();
HwcTest. c
#include "hwcTest.h"void realFunction(void *input){for(int i = 0;i < 5;i++){printf("%d\n",i);sleep(1);}}hwcTestForGCD getFuncPointer(){return realFunction;}ViewController. swift
class ViewController: UIViewController{ var imageview = UIImageView(frame: CGRectMake(40,40,200,200)) override func viewDidLoad(){ super.viewDidLoad() var globalQueueDefault = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0)dispatch_async_f(globalQueueDefault,nil,getFuncPointer())println("dispatch is over") } override func didReceiveMemoryWarning(){ super.didReceiveMemoryWarning() } } Then, the output will be displayed.
0dispatch is over1234
Then, we change it to dispatch_sync and run the command to find the output.
012345dispatch is over
We can better understand what synchronization is and what Asynchronization is.
3. Understand parallel queues and serial queues
You can modify the code in viewcontroller.swf t to use one project or two.
A function is used here.
func dispatch_queue_create(_ label: UnsafePointer<Int8>, _ attr: dispatch_queue_attr_t!) -> dispatch_queue_t!
Parameters
Label String type queue identifier, usually used as com. companyname. productname. functionname
Attr. DISPATCH_QUEUE_SERIAL creates an ordered execution queue. DISPATCH_QUEUE_CONCURRENT creates an execution queue at the same time.
Complete ViewController code. Here, two tasks are submitted, and the output is used to determine whether the queue is a parallel queue or a serial queue.
class ViewController: UIViewController{ var imageview = UIImageView(frame: CGRectMake(40,40,200,200)) override func viewDidLoad(){ super.viewDidLoad() dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0)){for var i = 0;i < 5;i++ {NSLog("First task:%d",i)sleep(1)}}dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0)){for var j = 0;j < 5;j++ {NSLog("Second task:%d",j)sleep(1)}}println("dispatch is over") } override func didReceiveMemoryWarning(){ super.didReceiveMemoryWarning() } }
The execution output here is:
First task:0Second task:0First task:1Second task:1First task:2Second task:2First task:3Second task:3First task:4Second task:4
Code execution time: 4.03 s
Then, we use the serial execution queue
class ViewController: UIViewController{ var imageview = UIImageView(frame: CGRectMake(40,40,200,200)) override func viewDidLoad(){ super.viewDidLoad()var serialQueue = dispatch_queue_create(label: "com.test.helloHwc",attr:DISPATCH_QUEUE_SERIAL)dispatch_async(serialQueue){for var i = 0;i < 5;i++ {NSLog("First task:%d",i)sleep(1)}}dispatch_async(serialQueue){for var j = 0;j < 5;j++ {NSLog("Second task:%d",j) sleep(1)}}println("dispatch is over") } override func didReceiveMemoryWarning(){ super.didReceiveMemoryWarning() } }
Output here is
First task:0First task:1First task:2First task:3First task:4Second task:0Second task:1Second task:2Second task:3Second task:4
The code execution time is 8.06 seconds.
Let's see the difference between parallel execution and serial execution.
Therefore, it is important to remember that submitting non-process tasks to a parallel queue significantly improves the efficiency.
Next expected Update time, this weekend
BTY: if the image fails to be downloaded, the image may be deleted from the server due to time. Just find a URL.
Source image