GCD belongs to the system and thread management, the function is very powerful, more powerful than the last two times we shared Operation. There are a lot of old-timers have created very, very much information about GCD, because everyone is put in the GCD at the beginning of multi-threaded content sharing, so a lot of theoretical knowledge is put in the GCD part.

Ha ha ~ fortunately, the wrong peak travel of atypical technical house wise and martial arts, put some basic concepts in the last two articles. Greatly reduced the reading burden of this article.

Since predecessors are early hot yao many wheels, I do not want to introduce some basic theoretical knowledge. Anyway, any amount of words in the code will only cause people to close this article immediately. Besides, the reading volume of the last article about Operation is obviously not high. It seems that people don’t like it.

Let me be lazy. The point is to share some code.

It’s not that theoretical knowledge isn’t important. That’s all interviews ask. Moreover, theoretical knowledge directly affects the depth of understanding of technology and determines how far one can go on this road. Will he become a leader in his field, or will he simply apply it?

1. Basic knowledge of GCD

What? What about the basic concepts? Easy ~easy~easy~ just a few of the most important, do not know will affect the reading of the content of the article.

In fact, GCD and Operation are strikingly similar in many ways. Nonsense, are multithreading, the bottom are about the same, can not be similar!

There are only two steps to using GCD:

  • STEP ONE: Create a task.
  • Put tasks in a queue.

. ~! @ # $%…… & * # $% @! ~ @ # $%…… How many steps does it take to put an elephant in a fridge? ! Two step! Open the fridge door and put the elephant in! Otaku fat, now very want to kill you ah!

It really is. Inner OS: This is just to trick you into getting started and make you feel so easy.

1.1 Classification of tasks

There are only two ways to do a task: synchronous and asynchronous.

  • Asynchronous (asynchronous) the ability to start a new thread, and the ability to skip current code and continue.
  • Synchronous (synchronous) does not have the ability to start a new thread or to skip the current code and continue execution.
The name of the The ability to start new threads The ability to skip current code and continue execution
asynchronous There are There are
synchronous NULL NULL

In other words, asynchronous tasks are simply the ability to run multiple tracks and run multiple cars at the same time. Synchronization is only one lane, blocked also can’t fly past, can only obediently wait, one car after another.

Tasks are put into queues, following the first in first out principle. Take a disgusting example, like shitting, eat first, then eat later. Ha ha ~ see this analogy, don’t kill me ~

1.2 Queue classification

There are only two types of queues: Serial Dispatch Queue and Concurrent Dispatch Queue.

  • Serial Dispatch Queue: Tasks are executed one after the other in an orderly manner. After each task is completed, the next task is executed.

  • A Concurrent Dispatch Queue enables simultaneous execution of multiple tasks, automatically enabling multiple threads to execute multiple tasks simultaneously.

Yi? A little dizzy, why do I feel the same as the task classification just now? That’s right! That’s it.

Now, just to make sure you don’t get confused, we’ll call the Chinese name of the Queue Queue, so that it corresponds to the OperationQueue, so that you don’t get confused.

The Serial Queue and Concurrent Queue each have a special Queue.

Main Queue: a special type of Serial queue. Can only be executed in the main thread, and tasks in the main queue can only be executed when the main thread is idle. To refresh UI usage.

Global queue: a special type of Concurrent queue. Used to perform time-consuming operations.

You can also customize queues in GCD.

1.3 Beginning of permutation and combination

In the beginning, didn’t we say there were only two steps to using GCD: create a task and put it in a Queue?

There are two types of tasks: synchronous and asynchronous. There are four queues plus two special (not custom) ones. Come on, let’s start permutations and combinations. There are eight.

The name of the Ability to start new threads Ability to skip current code and continue
asynchronous can can
synchronous / /
Queue Serial queue Serial Concurrent queue concurrent The home side column of the main Global queue
Ability to execute multiple tasks simultaneously / can / can

Ha ha ha O(∩_∩)O ha ha ~😆😆😆😆


Thoroughly seasick 😓

OooO ↘ ┏ ━ ┓ ↙ oooO (on) – > ┃ ┃ you please (dead) \ (- > ┃ ┃) please) / _) ↗ ┗ ━ ┛ ↖ (_ /


Come on, let me tell you the truth. There are a few special cases.

Serial queuesSerial Queue Parallel linesconcurrent Queue The home side columnmain Queue Global queueglobal Queue
asynchronous A new threadSerial execution A new thread,Parallel execution No new thread, serial execution A new thread,Parallel execution
synchronous No new thread, serial execution No new thread, serial execution okWill be locked No new thread, serial execution

Look at the table above, so if you want to do things at the same time, of course you can’t choose synchronous tasks. Because it’s totally powerless! It could even cause a lock.

To do things at the same time, choose concurrent Queue + asynchronous, or global Queue + asynchronous. However, a global Queue is a special type of Concurrent Queue.

If you’re multitasking, the easiest thing to do at work is to use global Queue + asynchrony. Single task, UI refresh using main Queue + asynchronous.

It doesn’t matter if they don’t want to see it. At work, if you have multiple tasks, the preference is global Queue + asynchronous. Single task, UI refresh using main Queue + asynchronous.

2. Basic application of GCD

My mother ~ through the above analysis, finally, the most basic use of the two. Multi-task: Global Queue + asynchronous. Single task, UI refresh using main Queue + asynchronous.

To be honest, THIS is the first time I’ve ever made a bold simplification. Will be patted to death by the gods? Wait for ~ ~ ~ ~

2.1 global Queue+ Asynchronous task

IBAction func globalAsyn(_ Sender: Any) {// Create a global Queue. //get a global queuelet globalQueue = DispatchQueue.global()
    for i in0... 10 {// Use global queues to enable asynchronous tasks. //use the global queue , runin asynchronous
        globalQueue.async {
            print("I am No.\(i), current thread name is:\(Thread.current)")}}}Copy the code

Let’s look at the result of the run, printed out of order, and not in the main thread. This proves that multiple tasks are indeed executed out of order.

2.2 main Queue+ Asynchronous task

@ibAction func mainAsyn(_ sender: Any) {// Create a main Queue //get a main Queuelet mainQueue = DispatchQueue.main
    
    for i in0... 10 {// Use the main queue, runin asynchronous
        mainQueue.async {
            print("I am No.\(i), current thread name is:\(Thread.current)")}}}Copy the code

2.3 Practice: Realize asynchronous downloading of pictures

Requirement: download a picture asynchronously and display it in UI after downloading

The effect picture after implementation:

Ideas:

  1. In addition to the current UI action, open oneglobal Queue+ asynchronous, used to download pictures. Because the process can be time-consuming.
  2. When the download is complete, open onemain Queue+ asynchronous, the downloaded picture assigned value, refresh the UI.

This little Demo actually implements thread communication as well.

@IBAction func asynDownloadImage(_ sender: Any) {
    let imageVC = ImageVC()
    DispatchQueue.global().async {
        
        if let url = URL.init(string: "https://placebeard.it/355/140") {
            do {
                let imageData = try Data(contentsOf: url)
                letImage = UIImage(data: imageData) / DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + DispatchTimeInterval.seconds(2), execute: { imageVC.imageView.image = image imageVC.imageView .sizeToFit() }) } catch {print(error) } } } navigationController? .pushViewController(imageVC, animated:true)}Copy the code

3. GCD service quality (Priority)

Dispatchqosclass is a class encapsulated in Swift that describes the quality of service.

This is also seen in Operation. The higher the level, the more resources are allocated. But it’s not strictly based on the level.

This is an enumeration value:

public enum QoSClass {

    caseBackground // The background quality of service class.caseUtility // Utility quality of service class.case'default' // Default value, The default quality of service class.caseUserInitiated // The user-initiated quality of service class.caseUserInteractive // Used to perform user interaction, The user-interactive quality of service class.caseUnspecified // The absence of a quality of service class. Public Init? (rawValue: qos_class_t) public var rawValue: qos_class_t { get } }Copy the code

Looking at the enumerated values above, you can probably guess the priority. And the interface, the user must be high, the background quietly executed must be low.

The order is as follows: userInteractive -> userInitiated -> default -> utility -> background -> unspecified

That’s pretty much the basics. After checking, there are still scheduling groups, semaphores, blocking, etc. At this time found a written GCD foundation seems not too realistic, and do not want an article too long, then open it. Next time.

Finally, all the code is here: download it from gitHub and give it a Star ~(~ o ~ 3 ~) ~ love you

I wish you a happy New Year ~! ~!