Grand Central Dispatch (GCD) is a pretty good choice of what are you trying to do here, you can achieve this by using DispatchQueue and DispatchGroup, as follows:
Swift 3:
func doEverything(completion: @escaping () -> ()) {
let queue = DispatchQueue(label: "reverseDomain", attributes: .concurrent, target: .main)
let group = DispatchGroup()
group.enter()
queue.async (group: group) {
print("do alpha")
group.leave()
}
group.enter()
queue.async (group: group) {
print("do beta")
group.leave()
}
group.notify(queue: DispatchQueue.main) {
completion()
}
}
Or, you can implement it this way (which I find more readable):
func doEverything(completion: @escaping () -> ()) {
let queue = DispatchQueue(label: "reverseDomain", attributes: .concurrent, target: .main)
let group = DispatchGroup()
queue.async (group: group) {
print("do alpha")
}
queue.async (group: group) {
print("do beta")
}
group.notify(queue: DispatchQueue.main) {
completion()
}
}
Note that I removed the success
flag from the completion
closure.
At this case, "do beta" (the execution of the second queue.async
) won't be executed until "do alpha" (the execution of the first queue.async
) finished, and that's because queue
target is .main
. If you want to let both of queue.async
work concurrently, there is no need to create an extra queue, the same queue should does the work, by replacing:
let queue = DispatchQueue(label: "reverseDomain", attributes: .concurrent, target: .main)
with:
let queue = DispatchQueue(label: "reverseDomain", attributes: .concurrent)
Now, the system will control over how both of queue.async
tasks should work concurrently (and obviously, group.notify
will be executed after the tow of the tasks finish).
Hope this helped.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…