Проблема в том, что я вызываю функцию bla ({// block code}) в фоновой очереди.Однако bla () вызывает обработчик завершения в главном потоке из-за групп рассылки - Janosch Hübner
снова проверьте ваш фрагмент
func doSomeWork(completion: ()->()) {
let myGroup: DispatchGroup = DispatchGroup()
for _ in 0..<10 {
myGroup.enter()
getSomething {
myGroup.leave()
}
}
myGroup.notify(queue: DispatchQueue.main) { // this here is the key
completion()
}
}
и увидите, что, поскольку getSomething
синхронно, вы можете просто написать
func doSomeWork(completion: ()->()) {
//let myGroup: DispatchGroup = DispatchGroup()
for _ in 0..<10 {
//myGroup.enter()
getSomething {
//myGroup.leave()
}
}
//myGroup.notify(queue: DispatchQueue.main) { // this here is the key
completion()
//}
}
В случае, если getSomething
должен быть асинхронным, используйте соответствующий API для запуска его в некоторой группе
func doSomeWork(completion: ()->()) {
let myGroup: DispatchGroup = DispatchGroup()
let queue = DispatchQueue.global()
for _ in 0..<10 {
//myGroup.enter()
queue.async(group: myGroup) {
getSomething {
//myGroup.leave()
}
}
}
myGroup.notify(queue: DispatchQueue.main) { // this here is the key
completion()
}
}
Запуск completion()
в той же группенить (лучше сказать в той же очереди), что и doSomeWork(completion: ()->())
, проста.
func doSomeWork(completion: ()->()) {
let myGroup: DispatchGroup = DispatchGroup()
let queue = DispatchQueue.global()
for _ in 0..<10 {
//myGroup.enter()
queue.async(group: myGroup) {
getSomething {
//myGroup.leave()
}
}
}
//myGroup.notify(queue: DispatchQueue.main) { // this here is the key
myGroup.wait()
completion()
//}
}
проверьте следующую страницу игровой площадки и посмотрите, как DispatchQueue.concurrentPerform может изменить ваш дизайн и как работает уведомление от goup
import PlaygroundSupport
import Dispatch
PlaygroundPage.current.needsIndefiniteExecution = true
let q0 = DispatchQueue.global()
let q1 = DispatchQueue(label: "my_queue", attributes: .concurrent)
let g = DispatchGroup()
let g1 = DispatchGroup()
q0.async(group: g) {
print("1 message from \(q0): will do some concurrent jobs in the background")
DispatchQueue.concurrentPerform(iterations: 5, execute: { (i) in
sleep(1)
print("\t",i)
})
print("2 message from \(q0): all concurrent jobs done")
q0.async(group: g) {
print("3 some other long time running on group...")
sleep(3)
print("3 ex")
}
q0.async(group: g1) {
print("? some other long time running on gifferent group...")
sleep(4)
print("? ex")
}
g1.notify(queue: .main, execute: {
print("g1 empty")
})
}
print("4 continue on main")
g.notify(queue: q1) {
print("5 message from \(q1): finished a")
DispatchQueue.main.async {
sleep(1)
print("6 from main, should stop playground execution?")
//PlaygroundPage.current.finishExecution()
}
print("7 message from \(q1): finished b")
}
g1.notify(queue: .main) {
print("8 from main, g1 is empty.")
}
print(" ... continue")
который печатает в моем окружении
1 message from <OS_dispatch_queue_global: com.apple.root.default-qos>: will do some concurrent jobs in the background
4 continue on main
... continue
8 from main, g1 is empty.
0
2
1
3
4
2 message from <OS_dispatch_queue_global: com.apple.root.default-qos>: all concurrent jobs done
3 some other long time running on group...
? some other long time running on gifferent group...
3 ex
5 message from <OS_dispatch_queue_concurrent: my_queue>: finished a
7 message from <OS_dispatch_queue_concurrent: my_queue>: finished b
6 from main, should stop playground execution?
? ex
g1 empty