當所有異步請求都完成時收到通知。只有在完成所有同步請求後才發出信令通知
我在下面的循環中多次呼叫registerTrack
。我只想觸發syncGroup.notify
時全部請求已完成。從看這個代碼,在registerTrack
每次成功完成之後,它會去notify
。只有在所有registerTrack
操作完成後,我如何才能使其顯示notify
?
我的代碼如下:
var fail = false
let syncGroup = DispatchGroup() //used so we can determine if all the register requests have finished
for track in unsyncedTracks {
syncGroup.enter()
if fail {
syncGroup.leave()
break //might save an aync request from getting executed on failure
}
registerTrack(track: track, withCompletion: { (success: Bool) ->() in
if success {
self.debug.log(tag: "RecordViewController", content: "Registered track: \(track.name)")
syncGroup.leave()
}
else {
fail = true
syncGroup.leave()
}
})
}
//all requests complete
syncGroup.notify(queue: .main) {
if fail {
complete(false)
}
else {
self.debug.log(tag: "RecordViewController", content: "Finished registering all unsynced tracks")
complete(true)
}
}
編輯:
基於使用GCD併發隊列的建議,我改變了我的代碼:
var failed = false
//work item to loop through and call registerTrack on each track
let registerTracksWorkItem = DispatchWorkItem {
for track in unsyncedTracks {
if failed { //exit early on failure, potentially save a network request
break
}
self.registerTrack(track: track, withCompletion: { (success: Bool) ->() in
if success {
self.debug.log(tag: "RecordViewController", content: "Registered track: \(track.name)")
}
else {
failed = true
}
})
}
}
//handler for when all registerTrack calls are complete
registerTracksWorkItem.notify(queue: DispatchQueue.main) {
if failed {
self.debug.log(tag: "RecordViewController", content: "At least one registerTrack call failed")
complete(false)
}
else {
self.debug.log(tag: "RecordViewController", content: "Finished registering all unsynced tracks")
complete(true)
}
}
//execute the work item
let queue = DispatchQueue.global()
queue.async(execute: registerTracksWorkItem)
此代碼不等待registerTrack
完成,而是執行它們並調用notify
事件。 :(
編輯3:
所以這個作品它使用一個計數器進行檢查,看其是否在最後unsyncedTracks
對象
var fail = false
let syncGroup = DispatchGroup() //used so we can determine if all the register requests have finished
//used to make sure notify is only triggered when all registerTracks are complete
let unsyncedTracksCount = unsyncedTracks.count
var completeCounter = 0
syncGroup.enter()
for track in unsyncedTracks {
registerTrack(track: track, withCompletion: { (success: Bool) ->() in
if success {
self.debug.log(tag: "RecordViewController", content: "Registered track: \(track.name)")
}
else {
fail = true
}
completeCounter = completeCounter + 1
if completeCounter == unsyncedTracksCount {
syncGroup.leave()
}
})
}
//all requests complete
syncGroup.notify(queue: .main) {
if fail {
complete(false)
}
else {
self.debug.log(tag: "RecordViewController", content: "Finished registering all unsynced tracks")
complete(true)
}
}
我能做到這一點(它也出現工作。 )?我加了,如果失敗,leave()
如果。
var fail = false
let syncGroup = DispatchGroup() //used so we can determine if all the register requests have finished
//used to make sure notify is only triggered when all registerTracks are complete
let unsyncedTracksCount = unsyncedTracks.count
var completeCounter = 0
syncGroup.enter()
for track in unsyncedTracks {
if fail { //might save an aync request from getting executed on failure
syncGroup.leave()
break
}
registerTrack(track: track, withCompletion: { (success: Bool) ->() in
if success {
self.debug.log(tag: "RecordViewController", content: "Registered track: \(track.name)")
}
else {
fail = true
}
completeCounter = completeCounter + 1
if completeCounter == unsyncedTracksCount {
syncGroup.leave()
}
})
}
//all requests complete
syncGroup.notify(queue: .main) {
if fail {
complete(false)
}
else {
self.debug.log(tag: "RecordViewController", content: "Finished registering all unsynced tracks")
complete(true)
}
}
將多個異步調用放入循環中並不是很好的設計。 GCD的併發隊列可能非常適合您的問題。這樣你可以運行所有的registerTracks任務,並知道它們什麼時候全部完成。 https://developer.apple.com/library/content/documentation/General/Conceptual/ConcurrencyProgrammingGuide/OperationQueues/OperationQueues.html – Gruntcakes
@Essenceofchicken你有沒有例子?謝謝。 – toast
我在上面添加了一個Apple文檔的鏈接,裏面有代碼片段。 – Gruntcakes