すべての非同期要求が完了したときに通知を受け取ります。すべての同期要求が完了した後にのみ通知が行われます
私は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)
}
}
EDIT::次のように
私のコードは、このコードにはない
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)
:GCD同時キューを使用する勧告に基づい
を、私はに私のコードを変更しましたregisterTrack
が終了するのを待って、すべてを実行し、notify
イベントを呼び出します。 :(
EDIT 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のドキュメントに上記のリンクを追加しました。そこにtheresのコードスニペットが追加されました。 – Gruntcakes