2015-10-19 27 views
1

比方说,我有以下代码:dispatch_async何时实际派遣?

dispatch_async(dispatch_get_main_queue()) { 
    myFunction() 
} 

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

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

+0

按照async的定义,执行的顺序是不确定的 - 操作系统将决定是否抢占。所以你不应该将你的代码放在特定的预期结果上。 – kfmfe04

+0

@ kfmfe04这是不正确的。主队列是一个串行队列,这意味着第二个任务不能同时执行。据推测,调用dispatch_async的代码是当前在主队列上执行的任务,并且该任务必须在另一个任务(即我正在排队的任务)执行之前完成。这是我想确认的。 – Ana

+2

正如你所说,主队列是一个串行队列,所以你的当前任务不会被抢占,并且执行的顺序不是不确定的;任务将按照他们提交给队列的顺序执行。这意味着,您不能说,当派遣模块将执行时,您不知道在添加的任务之前队列中还有哪些任务可能在队列中。所有你可以肯定地说,它会执行'以后' – Paulw11

回答

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. 块上dispatch_get_main_queue()运行,或
  3. 将单个版本1源分派到其回调。

如果上下文是输入源或定时器火灾,那么任务将在不同的迭代运行循环的发生。如果上下文是派发任务,那么该任务实际上可以在运行循环的相同迭代内运行。

0

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

总之,如果你异步分派从主队列中的主队列,派出块将不运行,直到你屈服回到主运行循环(也经过任何其它块分派到主队列也完)。