2015-10-19 31 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

什麼時候在這種情況下實際調用這個塊?我的當前隊列是否被搶佔並且塊是否立即運行,或者當前調用堆棧是否展開並且塊在下一個事件循環中被調用?或者是其他東西?

總之,如果你異步分派從主隊列中的主隊列,派出塊將不運行,直到你屈服回到主運行循環(也經過任何其它塊分派到主隊列也完)。