Photo by Sébastien Goldberg on Unsplash
Mount Cook, Nouvelle-Zélande
當你需要跟踪多個異步任務的完成時,DispatchGroup
是一個非常有用的工具。下面是一個使用 SwiftUI 和 DispatchGroup
的例子,其中我們模擬了從多個資源獲取數據的情境:
struct PublicSwimmingPoolsView: View {
let pools = Bundle.main.decode([PoolsSection].self, from: "pools.json")
@State private var data1: String = "Loading Data 1..."
@State private var data2: String = "Loading Data 2..."
@State private var allDataLoaded: Bool = false
var body: some View {
NavigationView {
VStack {
List {
/.../
}
Group {
VStack(spacing: 20) {
Text(data1)
Text(data2)
if allDataLoaded {
Text("All data loaded!")
}
}
.onAppear {
fetchData()
}
}
}
}
/.../
}
func fetchData() {
let dispatchGroup = DispatchGroup()
dispatchGroup.enter()
DispatchQueue.global().asyncAfter(deadline: .now() + 1) {
self.data1 = "Data 1 Fetched!"
dispatchGroup.leave()
}
dispatchGroup.enter()
DispatchQueue.global().asyncAfter(deadline: .now() + 2) {
self.data2 = "Data 2 Fetched!"
dispatchGroup.leave()
}
dispatchGroup.notify(queue: .main) {
self.allDataLoaded = true
}
}
}
在這個例子中:
DispatchGroup
。dispatchGroup.enter()
。dispatchGroup.leave()
。dispatchGroup.notify
,我們可以設定一個塊,該塊將在所有的 .enter()
被 .leave()
匹配調用之後執行。在這裡,我們更新了 allDataLoaded
以在 UI 中表示所有數據都已加載。這個模式對於確保多個異步任務都完成後再進行某些操作非常有用。
Tips : 每當開啟 dispatchGroup.enter(),確保 dispatchGroup.leave() ,要不然會永遠困在 dispatchGroup 🥺
我就遇到這 bug 單,特殊條件開啟新的 dispatchGroup.enter(),好多層 function 一層傳一層,最後沒加到 dispatchGroup.leave() 一行,突然找問題點藏很深 🥺
什麼!!妳還是不懂 dispatchGroup.enter() 沒有 dispatchGroup.leave(), dispatchGroup.notify 會怎樣?
來,開啟妳的啤酒,隨意坐坐 ~ 橋下說書人 Michael 來講故事:
在古老的魔法大陸上,有個精靈法師公會,名叫「Dispatch Guild」。公會中有一座大樹,有樹門,稱為「Group Portal」。每當有一對新人要結婚,都要同一個時間分別獨自進入這魔法門參加試煉。他們會使用dispatchGroup.enter()
這個咒語打開這座大門,分別進入另一個空間去完成任務。
但是,這個空間有一個規則。每當一個法師使用dispatchGroup.enter()
進入,門後的守護神就會增加一個計數。只有當每一位進入的法師都完成任務,使用dispatchGroup.leave()
咒語後,計數才會減少。
為什麼這很重要呢?因為門後的守護神需要確保每位法師都安全返回。只有當所有的法師都回來,計數歸零時,dispatchGroup.notify
的強大咒語就會被觸發,告訴大家:「冒險已經結束,可以回家了!」。
但是,傳說中有一些不小心的法師,他們進入空間後忘記使用dispatchGroup.leave()
。守護神在無窮無盡的時間中等待著他們的返回。這使得另一半一起都被困在那個空間裡,無法返回現實世界,也無法啟動dispatchGroup.notify
的強大咒語。
這是一個大問題!因為如果不小心,一對新人可能都會消失在那個空間中,永遠不會回來。
所以,每一次當一對新人進入那個空間,公會的長老都會嚴肅地警告他們:「當你完成你的任務,千萬不要忘記使用dispatchGroup.leave()
這個咒語,否則你會使另一半陷入危機!」。
在數千年的時間裡,這些法師們學會了尊重這個咒語和守護神的規則。他們知道,只有這樣,他們才能保證每次冒險後都能安全返回,享受勝利的喜悅。
下集待續