一、DispatchGroup三種用法:
1. notify(依賴任務)
let group = DispatchGroup()
myQueue?.async(group: group, qos: .default, flags: [], execute: {
for _ in 0...10 {
print("耗時任務一")
}
})
myQueue?.async(group: group, qos: .default, flags: [], execute: {
for _ in 0...10 {
print("耗時任務二")
}
})
//執行完上面的兩個耗時操作, 回到myQueue隊列中執行下一步的任務
group.notify(queue: myQueue!) {
print("回到該隊列中執行")
}
2. wait(任務等待)
let group = DispatchGroup()
myQueue?.async(group: group, qos: .default, flags: [], execute: {
for _ in 0...10 {
print("耗時任務一")
}
})
myQueue?.async(group: group, qos: .default, flags: [], execute: {
for _ in 0...10 {
print("耗時任務二")
sleep(UInt32(3))
}
})
//等待上面任務執行,會阻塞目前線程,逾時就執行下面的,上面的繼續執行。可以無限等待 .distantFuture
let result = group.wait(timeout: .now() + 2.0)
switch result {
case .success:
print("不逾時, 上面的兩個任務都執行完")
case .timedOut:
print("逾時了, 上面的任務還沒執行完執行這了")
}
print("接下來的操作")
3. enter leave 手動管理group計數,enter和leave必須配對
let group = DispatchGroup()
group.enter()//把該任務添加到組隊列中執行
myQueue?.async(group: group, qos: .default, flags: [], execute: {
for _ in 0...10 {
print("耗時任務一")
group.leave()//執行完之後從組隊列中移除
}
})
group.enter()//把該任務添加到組隊列中執行
myQueue?.async(group: group, qos: .default, flags: [], execute: {
for _ in 0...10 {
print("耗時任務二")
group.leave()//執行完之後從組隊列中移除
}
})
//當上面所有的任務執行完之後通知
group.notify(queue: .main) {
print("所有的任務執行完了")
}
二、項目中的實際用例
這次遇到的是一個循環網絡請求的功能(怎麼老是遇上這種蛋疼的API),要求本地存儲的數組裡循環取出存儲對象,并使用存儲對象的屬性做參數,POST請求。然後将每次請求下來的資料進行累加計算,最後指派。上代碼:
func sumTheassets(compHandler:@escaping (_ sum:Float)->()) {
var asset:Float = 0
let group = DispatchGroup() //建立group
for object in objects { //for循環便利本地存儲的數組資料
group.enter() // 将以下任務添加進group
let cellViewmodel = MyassetsCellViewModel() // 建立VM對象,并調用網絡請求函數
cellViewmodel.getThepriceFromnew(symbol: object.symbol, compHandler: { (price, ratio) in
let decimals = Float(object.decimals) // 擷取數量,轉為Float型
let num = price * decimals! //計算總價格 單價 * 數量
asset += num //将計算結果累加
group.leave() //本次任務完成(即本次for循環任務完成),将任務從group中移除
})
}
group.notify(queue: .main) { // group中的所有任務完成後再主線程中調用回調函數,将結果傳出去
compHandler(asset) //在回調裡将累加結果傳出去
}
}
以上,祝大家在開發中都不遇到奇葩API接口或需求 (美好的理想啊)