Differencein Approach to Create Dispatchqueue Swift3

What is the difference in approach to create DispatchQueue Swift3

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.

Swift 3: Difference between DispatchQueue.main.async{} and DispatcQueue.main.async(execute:{})?

What you're referring to is called trailing closure syntax. It's a syntactic sugar for making closures easier to work with.

There are many other kinds of syntactic sugar features that pertain to closures, which I cover in my answer here.

As always, I highly recommend the Swift Language guide, which does a great job at explaining the basics like this.

How to create dispatch queue in Swift 3

Creating a concurrent queue

let concurrentQueue = DispatchQueue(label: "queuename", attributes: .concurrent)
concurrentQueue.sync {

}

Create a serial queue

let serialQueue = DispatchQueue(label: "queuename")
serialQueue.sync {

}

Get main queue asynchronously

DispatchQueue.main.async {

}

Get main queue synchronously

DispatchQueue.main.sync {

}

To get one of the background thread

DispatchQueue.global(qos: .background).async {

}

Xcode 8.2 beta 2:

To get one of the background thread

DispatchQueue.global(qos: .default).async {

}

DispatchQueue.global().async {
// qos' default value is ´DispatchQoS.QoSClass.default`
}

If you want to learn about using these queues .See this answer

GCD differences in Swift 3

Beside not weakifying self in the first approach, both calls are equivalent.

Whether or not to create a variable is up to your (convenience) preferences and does not make a difference technically.

Difference between DispatchQueue.main.async and DispatchQueue.main.sync

When you use async it lets the calling queue move on without waiting until the dispatched block is executed. On the contrary sync will make the calling queue stop and wait until the work you've dispatched in the block is done. Therefore sync is subject to lead to deadlocks. Try running DispatchQueue.main.sync from the main queue and the app will freeze because the calling queue will wait until the dispatched block is over but it won't be even able to start (because the queue is stopped and waiting)

When to use sync? When you need to wait for something done on a DIFFERENT queue and only then continue working on your current queue

Example of using sync:

On a serial queue you could use sync as a mutex in order to make sure that only one thread is able to perform the protected piece of code at the same time.

What is difference between Dispatch Queue Priority and QoS in Dispatch Queue?

Apple has deprecated Dispatch queue priority from iOS 8.0 instead of that we can use Quality of service.

So Basically QOS and priority does same thing.

share DispatchQueue and dispatch_queue_t between Swift3 and Objective-c code

TLDR: You can just pass the DispatchQueue object to Objective C, it is the same object as the dispatch_queue_t.


dispatch_queue_t is defined like so in Objective C:

typedef NSObject<OS_dispatch_queue> *dispatch_queue_t;

Internally, a OS_dispatch_queue class exists, which, according to the Swift sources, is mapped to DispatchQueue:

Classes:
- Name: OS_dispatch_object
SwiftName: DispatchObject
- Name: OS_dispatch_queue
SwiftName: DispatchQueue

It is then further extended for Swift-specific API, but that API passes the DispatchQueue object directly into Objective C. See for instance call to _swift_dispatch_sync:

@available(OSX 10.10, iOS 8.0, *)
public func sync(execute workItem: DispatchWorkItem) {
// _swift_dispatch_sync preserves the @convention(block) for
// work item blocks.
_swift_dispatch_sync(self, workItem._block)
}

_swift_dispatch_sync is implemented like so:

void
swift::_swift_dispatch_sync(
__swift_shims_dispatch_queue_t queue,
__swift_shims_dispatch_block_t block)
{
dispatch_sync(cast(queue), cast(block));
}

Server Side Swift - Dispatch Queues

Perhaps you are thinking that DispatchQueue is middleware that runs in a separate process. DispatchQueue runs in the same process as the rest of your application and so if your server process crashes, it would crash along with it. To work around this, you would want to either build your own queue that runs in a separate process (and probably uses a shared backend for queuing/messaging) or use a package like SwiftQ.



Related Topics



Leave a reply



Submit