Хорошо, значит, вы правильно используете функцию ввода / вывода DispatchGroup
, но у вас возникают проблемы с доступом к их результатам.Я думаю, что вы ошибаетесь, пытаясь использовать как wait
, так и notify
, эти две функции предоставляют две разные функциональные возможности, которые обычно не используются вместе.После настройки ваших рабочих элементов, как вы сделали, у вас есть две опции:
- Подход
wait
Эта функция блокирует очередь вызовов и ожидает синхронно либо для прошедшего времени в стене, либо для завершения всех рабочих элементов в группе.Поскольку он блокирует вызывающего, важно всегда иметь таймаут в этой функции.
Подход
notify
Функция принимает целевую очередь и блок, который нужно запустить после завершения всех рабочих элементов в вашей группе.Здесь вы в основном просите систему уведомить вас, асинхронно , как только все рабочие элементы будут выполнены.Поскольку это асинхронный , мы обычно меньше беспокоимся о тайм-ауте, он ничего не блокирует.
Асинхронный
wait
(кажется, это то, что вы хотите?)
Если, как вам кажется, мы хотим получить уведомление, как только все рабочие элементы будут завершены, но также естьтайм-аут, мы должны сделать это сами, и это не так сложно.Мы можем добавить простое расширение для класса DispatchGroup
...
extension DispatchGroup {
func notifyWait(target: DispatchQueue, timeout: DispatchTime, handler: @escaping (() -> Void)) {
DispatchQueue.global(qos: .default).async {
_ = self.wait(timeout: timeout)
target.async {
handler()
}
}
}
}
Эта простая функция отправляет асинхронно в глобальную фоновую очередь, затем вызывает wait, которая будет ожидать завершения всех рабочих элементов, илиуказанное время ожидания, в зависимости от того, что наступит раньше.Затем он перезвонит вашему обработчику в указанной очереди.
Так что это теория, как вы можете использовать это.Мы можем сохранить ваши первоначальные настройки точно такими же
let myGroup = DispatchGroup()
var result = [Data]()
for i in 0 ..< 5 {
myGroup.enter()
Alamofire.request("https://httpbin.org/get", parameters: ["foo": "bar"]).responseJSON { response in
print("Finished request \(i)")
result.append(response.data)
myGroup.leave()
}
}
, а затем использовать нашу новую функцию, чтобы дождаться окончания
myGroup.notifyWait(target: .main,
timeout: DispatchTime.now() + 10) {
// here you can access the `results` list, with any data that has
// been appended by the work items above before the timeout
// was reached
}