Потокобезопасные очереди - PullRequest
1 голос
/ 18 мая 2019

Я выполняю 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, однако печатает ноль.

1 Ответ

0 голосов
/ 18 мая 2019

Конечно, это так, потому что конец функции не является end с точки зрения временной шкалы.Строка 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)
    }
}

Имейте в виду, что ваш код надежно завершает работу при возникновении ошибки ...

И ваша пользовательская очередь фактически избыточна, и вы выполняете 2 1 задачи

...