Вызов async(group:os:flags:execute:)
API, который вы используете, используется при выполнении задач, которые сами по себе являются синхронными. Например, предположим, что вы собирались обрабатывать кучу изображений в каком-то медленном синхронном API, но хотели запустить это параллельно, в фоновых потоках, чтобы избежать блокировки основного потока. Тогда вы должны использовать async(group:execute:)
API:
let group = DispatchGroup()
for image in images {
DispatchQueue.global().async(group: group) {
self.process(image)
}
}
group.notify(queue: .main) {
// all done processing the images
}
Однако в этом случае отдельные вызовы API анимации на основе блоков UIView
выполняются асинхронно. Таким образом, вы не можете использовать этот шаблон async(group:execute:)
. Вы должны вручную enter
перед запуском каждого асинхронного процесса, а затем leave
внутри соответствующих закрытий завершения, сопоставив их один к одному:
animationGroup.enter()
UIView.animate(withDuration: 1, animations: {
box.center = CGPoint(x: 150, y: 150) // Move box to lower right corner
}, completion: { _ in
UIView.animate(withDuration: 2, animations: {
box.transform = CGAffineTransform(rotationAngle: .pi / 4) // Rotate box 45 degrees
}, completion: { _ in
animationGroup.leave()
})
})
animationGroup.enter()
UIView.animate(withDuration: 4, animations: {
view.backgroundColor = .blue // Change background color to blue
}, completion: { _ in
animationGroup.leave()
})
animationGroup.notify(queue: .main) {
print("Animations Completed!")
}