Я выполняю 20 задач данных с разными URL-адресами и заполняю массив результатами, но в конце функции я все еще не получаю окончательный массив, несмотря на использование той же очереди.
class func getImages(photos:[Photo]){
var images:[UIImage?] = []
let arrayQueue = DispatchQueue(label: "imagesQueue",attributes: .concurrent)
for i in 0...20{
let url = EndPoints.getImage(farm: photos[i].farm, server: photos[i].server, id: photos[i].id, secret: photos[i].secret).url
let task = URLSession.shared.dataTask(with: url) { (data, response, error) in
arrayQueue.async(flags: .barrier) {
let image = UIImage(data: data!)!
images.append(image)
}
}
task.resume()
}
arrayQueue.sync {
print(images.count)
}
}
Эта функция должна выводить 21, однако выводит ноль.





Конечно, это так, потому что конец функции не является конец с точки зрения временной шкалы. Строка print в конце метода выполняется непосредственно перед тем, как какой-либо результат задачи данных будет добавлен в очередь.
Вам нужно DispatchGroup, закрытие notify выполняется после выполнения всех задач.
class func getImages(photos:[Photo]) {
var images:[UIImage] = [] // Why optional?
let group = DispatchGroup()
let arrayQueue = DispatchQueue(label: "imagesQueue", attributes: .concurrent)
for i in 0...20{
let url = EndPoints.getImage(farm: photos[i].farm, server: photos[i].server, id: photos[i].id, secret: photos[i].secret).url
group.enter()
let task = URLSession.shared.dataTask(with: url) { (data, response, error) in
arrayQueue.async(flags: .barrier) {
let image = UIImage(data: data!)!
images.append(image)
group.leave()
}
}
task.resume()
}
group.notify(queue: arrayQueue) {
print(images.count)
}
}
Имейте в виду, что ваш код надежно аварийно завершает работу при возникновении ошибки...
И ваша пользовательская очередь на самом деле избыточна, и вы выполняете задачи 21.
Я знаю, что с этим что-то не так, иначе я бы не разместил это здесь :), спасибо за совет.