dispatch_async 什么时候实际发送?

When does dispatch_async actually dispatch?

假设我有以下代码:

dispatch_async(dispatch_get_main_queue()) {
    myFunction()
}

这表示要异步调用调用 myFunction 的块。假设我在我的主队列中调用此代码,该队列也是为 dispatch_async 调用指定的队列。

在这种情况下,这个块实际上是什么时候被调用的?我当前的队列是否被抢占并立即 运行 块,或者当前调用堆栈是否展开并在下一个事件循环中调用该块?或者是其他东西?

来自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.

来自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.

从这两条信息我们知道主队列是串行调度队列dispatch_async()会遵循串行执行的规则

所以简单的答案是任务将在当前上下文完成后的某个时间运行在主队列中。


我找不到 运行 循环内部的官方描述,但是 rob mayoff 一个很好的细分。

Order of operations in runloop on iOS

Note that the run loop is structured so only one of these branches happens on each iteration:

  1. Ready timers fire, or
  2. Blocks on dispatch_get_main_queue() run, or
  3. A single version 1 source is dispatched to its callback.

如果上下文是输入源或定时器触发,则任务将在 运行 循环的不同迭代中发生。如果上下文是分派的任务,则该任务实际上可能 运行 在 运行 循环的同一迭代中。

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?

简而言之,如果您从主队列异步分派到主队列,分派的块将不会运行,直到您回到主运行循环(以及任何其他分派到主队列的块也完成了)。