线程安全队列

时间:2019-05-18 13:21:31

标签: ios swift grand-central-dispatch urlsession

我正在执行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 :(得分:0)

之所以这样做,是因为该功能的 end 在时间轴上不是 end 。在将数据任务的任何结果添加到队列之前,将立即执行方法末尾的print行。

您需要DispatchGroupnotify关闭将在所有任务完成后执行。

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 个任务