Aleksey Timoshchenko Aleksey Timoshchenko - 4 years ago 148
Swift Question

What is the difference in approach to create DispatchQueue Swift3

I am a rookie in Swift, and there is such misunderstandings

what is the difference how to create dispatch queue

sample 1

let backgroundQueue = DispatchQueue(label: "com.app.queue",
qos: .background,
target: nil)

backgroundQueue.async {
print("Dispatched to background queue")
}


sample 2

let backgroundQueue = DispatchQueue.global()
backgroundQueue.async {
print("Dispatched to background queue")
}


as far as I understand this two approaches do the same

or for example this approach

DispatchQueue.global(qos: .userInitiated).async {
print("user initiated task")
}


what does it mean?

Rob Rob
Answer Source

The queue you create in your first example is your own custom serial queue. As the somewhat dated, yet still relevant, Concurrency Programming Guide says:

Serial queues (also known as private dispatch queues) execute one task at a time in the order in which they are added to the queue. The currently executing task runs on a distinct thread (which can vary from task to task) that is managed by the dispatch queue. Serial queues are often used to synchronize access to a specific resource.

You can create as many serial queues as you need, and each queue operates concurrently with respect to all other queues. In other words, if you create four serial queues, each queue executes only one task at a time but up to four tasks could still execute concurrently, one from each queue.

Whereas your latter examples are using simply retrieving system-provided global queues which are concurrent:

Concurrent queues (also known as a type of global dispatch queue) execute one or more tasks concurrently, but tasks are still started in the order in which they were added to the queue. The currently executing tasks run on distinct threads that are managed by the dispatch queue. The exact number of tasks executing at any given point is variable and depends on system conditions.

Now, you can nowadays create your own custom concurrent queue, but a global queue is simply a concurrent queue that was created for us.

So, what does this mean to you?

  • If you dispatch blocks to serial queue (your first example), only one block can run at any time. This makes it really useful for synchronizing memory access in multi-threaded apps, but can be used in any environment where you need a background queue, but you want dispatched blocks to be run serially (i.e. sequentially) with respect to other blocks on that queue.

  • The global queues that you are using in your latter examples are concurrent queues. This means that if you dispatch four separate tasks to this global queue, those blocks may run concurrently with respect to each other). This is ideal where you really want not only background execution, but don't care if these blocks also run at the same time as other dispatched blocks, too.

  • In your latter examples, where you're accessing a global queue, recognize that because those are system-provided, you have some modest limitations on your interaction with these queues, namely:

    • You cannot suspend global queues;

    • You cannot use barriers on global queues;
       

    But, with that notwithstanding, if you are just looking for an simple way of dispatching blocks to run in the background (and you don't care if those dispatched blocks run at the same time as each other), then global queues are incredibly simple and efficient way to do that.


By the way, the difference between your second example (for which I assume you intended let backgroundQueue = DispatchQueue.global()) and the third example, is merely that in your third example, you assigned the explicit quality of service (qos), whereas in your second example, you're using the default qos. FWIW, it's generally advisable to specify a qos, so that the OS can prioritize threads contending for limited system resources accordingly.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download