iOS| #28 | GCD 筆記 part2. DispatchGroup

iOS| #28提到了DispatchQueue的使用,這次會說明如何使用DispatchGroup搭配DispatchQueue應用。

Tommy
Apr 22, 2022
Photo by Andrew Moca on Unsplash

名詞解釋

在正式講解前有一些DispatchGroup的method可能要先熟悉一下

  1. notify
    當DispatchGroup中所有task都完成時,可以呼叫此函式做相對應的動作
  2. wait
    要等待前面的task完成才開始做下一動,可以呼叫此函式
  3. enter
    使用此函式代表DispatchGroup要產生新的block執行任務
  4. leave
    使用此函式代表先前生成的block任務已完成

程式範例

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

3. 生成DispatchGroup、DispatchQueue之後測試方便使用。

接下來會用程式範例在func dispatchGroupTest()中 print出一些東西來觀察利用DispatchGroup執行任務時的狀況

  • 多個任務同時處理,全數執行完成時觸發新的任務

某些時候我們可能要處理多項任務(無限制完成順序),等多項前置任務都完成時,最後再觸發一項任務。

例如:吃早餐之前,要先添加牛奶、麥片。但順序是沒有差的,吃進肚子裡都一樣。

結果如下:

從以下結果可以看得出來,前兩個任務:加麥片、加牛奶是平行處理的,所以重複執行時完成順序可能會不同。

第一次執行

加牛奶加麥片吃早餐

第二次執行

加麥片加牛奶吃早餐
  • 多個任務按照順序完成,全數執行完成時觸發新的任務

某些時候我們可能要處理多項任務,並且我們希望任務按照順序完成。等多項前置任務都完成時,最後再觸發一項任務。

例如:現在疫情當道,衛生習慣要稍微注意。所以當我們回到家要先開門、洗手、吃飯。我們希望這些任務照順序完成,前面任務都完成以後再執行吃飯後甜點的任務。

結果如下:

透過wait()的method,我們可以等待前一項任務完成再做後面的任務。
因此這邊print的結果一定都會照著我們期望的順序顯示。

開門洗手吃飯吃飯後甜點

補充:
在使用上會有一些要注意的地方,經過測試後將這些情境列在下方

  • 使用wait()等待前項任務完成,會讓程式碼停在wait()這邊,在此以後的其他任務會暫時不會被執行。

新增程式碼,等待五秒後再執行leave()。

queue.asyncAfter(deadline: .now() + 5) { //告訴group已經做完事了 dispatchGroup.leave()}

透過以下的執行結果可以觀察程式碼40行的print(“開完門了”)並沒有馬上被執行。因為使用wait()的緣故等到五秒後執行完leave()才會繼續往程式碼40行以後執行。

  • enter()數量大於leave()
  1. 無使用wait()的情況:
    notify()的任務永遠不會被執行
  2. 有使用wait()的情況:
    程式會因為wait()而卡住,後面的事情都不會做
  • leave()數量大於enter()

會閃退

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

--

--