iOS| #28 | GCD 筆記 part1. Dispatch Queue

在開發程式的過程中,我們不會只有一個任務要執行。任務可以是抓取資料、更新畫面、上傳資料等等。而我們當然會希望不要因為其他的任務而影響到UI介面顯示被卡住。
因此Apple提供了GCD(多執行序的功能)讓我們使用。

Tommy
15 min readApr 18, 2022
Photo by Melanie Pongratz on Unsplash

名詞解釋

  1. GCD(Grand Central Dispatch)
    為多執行序的應用,可以縮短任務達成時間、避免佔用主執行序導致UI畫面被卡住,影響使用者體驗
  2. Queue
    稱為佇列,是一種資料結構的型態,有著先進先出的特性。
    例如:排隊買車票,當前面的人購票完成才換下一個。
  3. Serial
    queue的屬性之一,屬性為serial的queue會依序執行任務,並且會等前面的任務執行完成再執行下個任務。
  4. Concurrent
    queue的屬性之一,屬性為concurrent的queue會按照順序“開始”執行任務。但在處理多項任務時是同時進行的,因此不會等前面的任務執行完畢再做下一個,每項工作的完成時間是不確定的。
  5. sync(同步)
    在queue中要執行的程式碼區塊(block),使用sync執行的話會依序執行block內的程式,且不會開啟新的執行序。
  6. async(非同步)
    在queue中要執行的程式碼區塊(block),使用async執行的話會依序執行block內的程式,且會開啟新的執行序。

程式範例

  1. 首先建立一個project,實作func queueTest()。
  2. 在viewDidLoad()呼叫此func 。

3. 生成queue,日後會再來使用。
注意:attribute沒給預設會是serial的,若要使用concurrent可以利用參數attribute來設置。

4. 在main queue印出一些東西,日後會拿來跟queue比較執行任務的順序。

接下來會用程式範例在func queueTest()中 print出一些東西搭配BreakPoint來觀察不同的Queue&block組合執行任務時Thread的狀況

  • 建立 Serial Queue 與 sync block

結果如下:

按照任務順序完成,會等前面的任務執行完成再執行下個任務。

first block queue:❤️ 1first block queue:❤️ 2first block queue:❤️ 3first block queue:❤️ 4first block queue:❤️ 5first block queue:❤️ 6first block queue:❤️ 7first block queue:❤️ 8first block queue:❤️ 9first block queue:❤️ 10first block queue - 2 :❤️ 1first block queue - 2 :❤️ 2first block queue - 2 :❤️ 3first block queue - 2 :❤️ 4first block queue - 2 :❤️ 5first block queue - 2 :❤️ 6first block queue - 2 :❤️ 7first block queue - 2 :❤️ 8first block queue - 2 :❤️ 9first block queue - 2 :❤️ 10second block queue:❤️ 1second block queue:❤️ 2second block queue:❤️ 3second block queue:❤️ 4second block queue:❤️ 5second block queue:❤️ 6second block queue:❤️ 7second block queue:❤️ 8second block queue:❤️ 9second block queue:❤️ 10main queue:💙 100main queue:💙 101main queue:💙 102main queue:💙 103main queue:💙 104main queue:💙 105main queue:💙 106main queue:💙 107main queue:💙 108main queue:💙 109main queue:💙 110

利用BreakPoint觀察thread的情形:

可以看得出來不會產生新的thread,且使用Serial Queue 搭配 sync block其實就等於在main thread執行任務(如下圖同樣都在thread 1)。

  • 建立 Serial Queue 與 async block

結果如下:

按照任務順序完成,會等前面的任務執行完成再執行下個任務。
但因為使用async的緣故會產生新的thread,將任務送出去以後,系統會根據thread的qos(quality of service)自動分配資源給優先度較高的任務(此例來看是main thread較高)。

main queue:💙 100first block queue:❤️ 1main queue:💙 101first block queue:❤️ 2first block queue:❤️ 3first block queue:❤️ 4first block queue:❤️ 5first block queue:❤️ 6first block queue:❤️ 7first block queue:❤️ 8first block queue:❤️ 9first block queue:❤️ 10main queue:💙 102main queue:💙 103first block queue - 2 :❤️ 1main queue:💙 104first block queue - 2 :❤️ 2main queue:💙 105main queue:💙 106main queue:💙 107main queue:💙 108main queue:💙 109main queue:💙 110first block queue - 2 :❤️ 3first block queue - 2 :❤️ 4first block queue - 2 :❤️ 5first block queue - 2 :❤️ 6first block queue - 2 :❤️ 7first block queue - 2 :❤️ 8first block queue - 2 :❤️ 9first block queue - 2 :❤️ 10second block queue:❤️ 1second block queue:❤️ 2second block queue:❤️ 3second block queue:❤️ 4second block queue:❤️ 5second block queue:❤️ 6second block queue:❤️ 7second block queue:❤️ 8second block queue:❤️ 9second block queue:❤️ 10

利用BreakPoint觀察thread的情形:

可以看得出來會產生新的thread(但只有一個)如下圖中的Thread7,且與main thread平行處理任務。但系統會自動分配比較多資源給main thread使其優先完成。

  • 建立 Concurrent Queue 與 sync block

結果如下:

與Serial Queue 搭配sync block的結果相同。
按照任務順序完成,會等前面的任務執行完成再執行下個任務。

first block queue:❤️ 1first block queue:❤️ 2first block queue:❤️ 3first block queue:❤️ 4first block queue:❤️ 5first block queue:❤️ 6first block queue:❤️ 7first block queue:❤️ 8first block queue:❤️ 9first block queue:❤️ 10first block queue - 2 :❤️ 1first block queue - 2 :❤️ 2first block queue - 2 :❤️ 3first block queue - 2 :❤️ 4first block queue - 2 :❤️ 5first block queue - 2 :❤️ 6first block queue - 2 :❤️ 7first block queue - 2 :❤️ 8first block queue - 2 :❤️ 9first block queue - 2 :❤️ 10second block queue:❤️ 1second block queue:❤️ 2second block queue:❤️ 3second block queue:❤️ 4second block queue:❤️ 5second block queue:❤️ 6second block queue:❤️ 7second block queue:❤️ 8second block queue:❤️ 9second block queue:❤️ 10main queue:💙 100main queue:💙 101main queue:💙 102main queue:💙 103main queue:💙 104main queue:💙 105main queue:💙 106main queue:💙 107main queue:💙 108main queue:💙 109main queue:💙 110

利用BreakPoint觀察thread的情形:

可以看得出來不會產生新的thread,且使用Concurrent Queue 搭配 sync block其實就等於在main thread執行任務(如下圖同樣都在thread 1)。

  • 建立 Concurrent Queue 與 async block(執行效率最高的做法)

結果如下:

按照任務順序 “開始” 執行,且不會等前面的任務執行完成再執行下個任務,所有任務是 “同時” 進行的。
但因為使用async的緣故會產生新的thread,將任務送出去以後,系統會根據thread的qos(quality of service)自動分配資源給優先度較高的任務(此例來看是main thread較高)。

main queue:💙 100main queue:💙 101main queue:💙 102main queue:💙 103second block queue:❤️ 1second block queue:❤️ 2first block queue:❤️ 1main queue:💙 104second block queue:❤️ 3second block queue:❤️ 4second block queue:❤️ 5second block queue:❤️ 6first block queue:❤️ 2first block queue:❤️ 3second block queue:❤️ 7first block queue:❤️ 4main queue:💙 105second block queue:❤️ 8second block queue:❤️ 9second block queue:❤️ 10first block queue:❤️ 5main queue:💙 106first block queue:❤️ 6main queue:💙 107main queue:💙 108first block queue:❤️ 7main queue:💙 109main queue:💙 110first block queue:❤️ 8first block queue:❤️ 9first block queue:❤️ 10first block queue - 2 :❤️ 1first block queue - 2 :❤️ 2first block queue - 2 :❤️ 3first block queue - 2 :❤️ 4first block queue - 2 :❤️ 5first block queue - 2 :❤️ 6first block queue - 2 :❤️ 7first block queue - 2 :❤️ 8first block queue - 2 :❤️ 9first block queue - 2 :❤️ 10

補充:由於是平行處理(非同步)的緣故,所以每次執行的結果print出來的順序會有些許不同。

第二次執行結果如下:

second block queue:❤️ 1first block queue:❤️ 1main queue:💙 100main queue:💙 101second block queue:❤️ 2main queue:💙 102second block queue:❤️ 3first block queue:❤️ 2second block queue:❤️ 4main queue:💙 103second block queue:❤️ 5main queue:💙 104main queue:💙 105first block queue:❤️ 3main queue:💙 106second block queue:❤️ 6second block queue:❤️ 7second block queue:❤️ 8second block queue:❤️ 9first block queue:❤️ 4second block queue:❤️ 10main queue:💙 107main queue:💙 108main queue:💙 109main queue:💙 110first block queue:❤️ 5first block queue:❤️ 6first block queue:❤️ 7first block queue:❤️ 8first block queue:❤️ 9first block queue:❤️ 10first block queue - 2 :❤️ 1first block queue - 2 :❤️ 2first block queue - 2 :❤️ 3first block queue - 2 :❤️ 4first block queue - 2 :❤️ 5first block queue - 2 :❤️ 6first block queue - 2 :❤️ 7first block queue - 2 :❤️ 8first block queue - 2 :❤️ 9first block queue - 2 :❤️ 10

利用BreakPoint觀察thread的情形:

可以看得出來會產生新的thread(且會有多個)如下圖中的Thread4、Thread8,且與main thread平行處理任務。

補充:在巢狀的async block中的任務不一定會被分配到同一個thread中。

被分配到同個Thread中(Thread2)

被分配到不同個Thread中(Thread7、Thread2)

若內容有誤煩請指教,感謝收看。

--

--