最近接到一個需求,在載入一個畫面時要同時呼叫兩支API,分別得到result之後再將兩組資料二合為一。

這邊先不討論為什麼backend不能乾淨俐落的用一支API回傳就好,正所謂無風不起浪,事出必有因,總之要怎麼在確認兩支API都得到result之後再做後續的處理呢?

你可以先call一支API然後把另外一支包在裡面,如果有三支,就再包一支,最後程式碼看起來會長這樣:

{{{{{}}}}}

不知不覺寫了一段俄羅斯娃娃呢

 

優雅的擁抱GCD

GCD裡面提供的Dispatch Group可以在多個Dispatch Queue執行完之後,透過dispatch_group_notify來獲得通知

但若你的任務是一個非同步的網路請求呢?若將async的API request包在dispatch_group_async中,你會發現在API還沒接到result時dispatch_group_notify就接到通知了,這時咱先別急著把巢狀怪物搬回來交差了事,Dispatch Group還提供了兩個法寶:dispatch_group_enter與dispatch_group_leave

dispatch_group_enter & dispatch_group_leave

dispatch_group_enter這個方法用來計算group中的任務數,也就是說呼叫一次任務數就會+1,而dispatch_group_leave則相對的對任務數-1,因此在每個API request發出時下dispatch_group_enter,並在得到回傳結果時下dispatch_group_leave,當任務數為0時才會收到通知,感覺有點像ARC的retain count的概念。

因此就可以寫成:

Objc

Swift

這樣是不是比俄羅斯娃娃般的巢狀連環摳優雅多了呢~

參考資料:iOS 多线程GCD之dispatch_group