Reputation: 1355
I'd worked on Java, and pretty much clear with the working of threads and thread pool.
I was wondering if anyone can explain the working of how thread's are created and allocated space in the thread pool in swift ?.
Also, does
Dispatch.main.async {
// some code
}
Creates a new Thread or Asynchronously executes the task ?
Thanks in advance =)
Upvotes: 3
Views: 3333
Reputation: 19602
Your code queues the block of code on the main queue (Dispatch.main
) and returns immediately (.async
), before executing the code.
You do not have control over which thread is used by the queue. Even if you create an own queue:
let serialQueue = DispatchQueue(label: "queuename")
serialQueue.async {
...
}
you do not know which thread your code will be running on.
Update:
As correctly stated by Paulw11 in the comment,
... if you dispatch a task on the main queue, it is guaranteed to execute on the main thread. If you dispatch a task on any other queue, you don't know which thread it will execute on; it may execute on the main thread or some other thread.
Upvotes: 3
Reputation: 299595
Queues and threads are separate concepts. Queues are ordered (sometimes prioritized) sequences of blocks to execute. As (mostly) an implementation detail, blocks must be scheduled onto threads in order to execute, but this is not the major point of them.
So Dispatch.main.async
dispatches (appends) a block to the main queue. The main queue is serial and somewhat special in that it is promised to also be run exclusively on the main thread (as noted by Paulw11). It also promises to be associated with the main runloop. Understanding this "appends a block to a queue" concept is critical, because it has significant impact on how you design things in queues vs how you design things in threads. async
does not mean "start running this now." It means "stick this on a queue, but don't wait for it."
As a good example of how the designs can be different, placing something on a queue doesn't mean it will ever run (even without bugs or deadlocks). It is possible and useful to suspend queues so that it stops scheduling blocks. It's possible to tie queues to other queues so that when a queue "schedules" something, it just puts it onto another queue rather than executing it. There are lots of things you can do with queues unrelated to "run things in the background." You can attach completion handlers to blocks. You can use groups to wait on collections of blocks. GCD is a way of thinking about concurrency. Parallelism is just a side benefit. (A great discussion of this concept is Concurrency is not parallelism by Rob Pike. It's in Go, but the concepts still apply.)
If you call Dispatch.main.async
while running on the main queue, then that block is absolutely certain to not execute until the current block finishes. In UIKit and AppKit, "the current block finishes" often means "you return from a method that was called by the OS." While not implemented this way, you can pretend that every time you're called from the OS, it was wrapped in a call to Dispatch.main.async
.
This is also why you must never call Dispatch.main.sync
(note sync
) from the main queue. That block will wait for you to return, and you'll wait until the block finishes. A classic deadlock.
As a rule, the thread pool is not your business in iOS. It is an implementation detail. Occasionally you need to think about it for performance reasons, but if you are thinking too much about it, you probably are designing your concurrency incorrectly.
If you're coming from Java, you definitely want to read Migrating Away From Threads in the Concurrency Programming Guide. It's the definitive resource for how to rethink thread-based patterns in queues.
Upvotes: 14