问题
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?
回答1:
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.
回答2:
Not much different between the 3.
Sample 1 creates a queue that only your app has access to. You also set its label to com.app.queue
which can help you debug easier.
Sample 2 is not valid Swift code. I believe what you meant was:
let backgroundQueue = DispatchQueue.global(qos: .default) // or any other QoS
backgroundQueue.async {
print(backgroundQueue.label) // the label property tell you what queue it is
}
Same as sample 1, accept that you are using a system queue which is shared with other applications.
Sample 3 is simply a convenient method (save for the different QoS you specified):
DispatchQueue.global(qos: .userInitiated).async {
// you don't have any reference to the queue your code
// is running on, but most of times it's not needed
}
The majority of the code I wrote used something similar to Sample 3. Sample 2 is least common. Sample 1 is used mostly when you need to synchronize actions across multiple queues.
来源:https://stackoverflow.com/questions/42041894/what-is-the-difference-in-approach-to-create-dispatchqueue-swift3