dispatch_async什么时候实际调度?

时间:2015-10-19 00:04:29

标签: ios grand-central-dispatch

我们说我有以下代码:

dispatch_async(dispatch_get_main_queue()) {
    myFunction()
}

这就是调用异步调用myFunction的块。让我们说我在主队列中调用此代码,该队列也是为dispatch_async调用指定的队列。

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

2 个答案:

答案 0 :(得分:1)

来自Grand Central Dispatch (GCD) Reference: dispatch_async

  

目标队列确定是否相对于提交到同一队列的其他块串行或同时调用该块。

来自OperationQueues: Performing Tasks on the Main Thread

  

您可以通过调用dispatch_get_main_queue函数来获取应用程序主线程的调度队列。添加到此队列的任务在主线程本身上串行执行。因此,您可以将此队列用作在应用程序的其他部分中完成工作的同步点。

从这两条信息中,我们知道主队列是一个串行调度队列,dispatch_async()将遵循串行执行规则。

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

我找不到运行循环内部的正式描述,但是rob mayoff很好地分解了。

Order of operations in runloop on iOS

  

请注意,运行循环的结构是每次迭代时只发生其中一个分支:

     
      
  1. 准备好计时器,或
  2.   
  3. 阻止dispatch_get_main_queue()运行或
  4.   
  5. 将单个版本1源分派给其回调。
  6.   

如果上下文是输入源或计时器触发,则任务将在运行循环的不同迭代中发生。如果上下文是一个调度任务,那么该任务实际上可以在运行循环的同一次迭代中运行。

答案 1 :(得分:1)

  

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

简而言之,如果从主队列异步调度到主队列,则调度块将不会运行,直到您回退到主运行循环(并且在调度到主队列的任何其他块也完成之后)。