Reputation:
Let's say I have the following code:
dispatch_async(dispatch_get_main_queue()) {
myFunction()
}
This says to call the block, which calls myFunction
, asynchronously. Let's say that I call this code in my main queue, which is also the queue specified for the dispatch_async
call.
When does this block actually get called in this case? Does my current queue get pre-empted and the block run immediately, or does the current call stack unroll and the block gets called at the next event loop? Or something else?
Upvotes: 2
Views: 495
Reputation: 438467
When does this block actually get called in this case? Does my current queue get pre-empted and the block run immediately, or does the current call stack unroll and the block gets called at the next event loop? Or something else?
In short, if you dispatch asynchronously to the main queue from the main queue, the dispatched block will not run until you yield back to the main run loop (and also after any other blocks dispatched to the main queue also finish).
Upvotes: 2
Reputation: 42598
From Grand Central Dispatch (GCD) Reference: dispatch_async
The target queue determines whether the block is invoked serially or concurrently with respect to other blocks submitted to that same queue.
From OperationQueues: Performing Tasks on the Main Thread
You can get the dispatch queue for your application’s main thread by calling the dispatch_get_main_queue function. Tasks added to this queue are performed serially on the main thread itself. Therefore, you can use this queue as a synchronization point for work being done in other parts of your application.
From these two pieces of information, we know the main queue is a serial dispatch queue and dispatch_async()
will follow the rules of serial execution.
So the simple answer is the task will be run on the main queue sometime after the completion of the current context.
I couldn't find a official description of the run loop's internals, but rob mayoff a good breakdown.
Order of operations in runloop on iOS
Note that the run loop is structured so only one of these branches happens on each iteration:
- Ready timers fire, or
- Blocks on dispatch_get_main_queue() run, or
- A single version 1 source is dispatched to its callback.
If the context is an input source or a timer fire, then the task will happen in a different iteration of the run loop. If the context is a dispatched task, then the task may actually run within the same iteration of the run loop.
Upvotes: 1