【问题标题】:Swift - Block loop from continuing until download operation finishesSwift - 阻止循环继续直到下载操作完成
【发布时间】:2017-08-02 04:29:09
【问题描述】:

我目前正在尝试根据用户对游戏的请求下载多个文件。我的目标是让它一次只下载一个文件并停止执行代码,直到该文件完成下载。

我的代码是一个 JSON 对象数组,每个对象都包含一个用于下载它们的路径(路径)和文件的 URL。我正在遍历数组并使用 AlamoFire 通过 .downloadProgress 闭包下载它们。

Alamofire.download(
json["url"].stringValue,
method: .get,
to: destination).downloadProgress(closure: { (Alamoprogress) in
info.stringValue = "Downloading: " + filename
progress.doubleValue = Alamoprogress.fractionCompleted * 100
}).response(completionHandler: { (DefaultDownloadResponse) in
})

为了确保一次只下载一个文件,我设置了一个 DispatchQueue 并将 Alamofire 请求移动到同步操作中:

for jsonObject in jsonArray{
    queue.async {
    print("Started downloading " + filename)
    info.stringValue = "Downloading: " + filename
    info.placeholderString = "Downloading: " + filename
    info.isEnabled = true
    info.isHidden = false
    progress.isHidden = false
    let destination: DownloadRequest.DownloadFileDestination = { _, _ in
        let documentsURL = filepath
        return (documentsURL, [.removePreviousFile])
    }
    Alamofire.download(
        json["url"].stringValue,
        method: .get,
        to: destination).downloadProgress(closure: { (Alamoprogress) in
                info.stringValue = "Downloading: " + filename
            progress.doubleValue = Alamoprogress.fractionCompleted * 100
        }).response(completionHandler: { (DefaultDownloadResponse) in
                            })
           }
}

但是,调试日志会在下载文件时继续循环,并a同步下载它们。这会导致info 框和progress 栏在下载时发疯,因为它会同时下载它们。我相信我已经设置了一个同步循环,但是它可能仍然是异步的,因为它是循环的。

这里如何防止异步下载?

【问题讨论】:

  • 您发布的代码中没有循环。
  • @rmaddy 我已经更新它以包含循环,我之前所拥有的只是循环中的内容。

标签: swift asynchronous foreach alamofire


【解决方案1】:

使用信号量,因此一次只下载一个:

let semaphore = DispatchSemaphore(value: 1)

for jsonObject in jsonArray {
    queue.async {
        semaphore.wait()

        print("Started downloading " + filename)
        info.stringValue = "Downloading: " + filename
        info.placeholderString = "Downloading: " + filename
        info.isEnabled = true
        info.isHidden = false
        progress.isHidden = false
        let destination: DownloadRequest.DownloadFileDestination = { _, _ in
            let documentsURL = filepath
            return (documentsURL, [.removePreviousFile])
        }
        Alamofire.download( json["url"].stringValue, method: .get, to: destination)
            .downloadProgress{ Alamoprogress in
                info.stringValue = "Downloading: " + filename
                progress.doubleValue = Alamoprogress.fractionCompleted * 100
            }
            .response { response in
                semaphore.signal()
            }
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-09-24
    • 1970-01-01
    • 2019-11-20
    • 2019-12-15
    • 1970-01-01
    • 2015-04-14
    • 2013-01-10
    • 2015-03-25
    相关资源
    最近更新 更多