【问题标题】:UI update not working for urlSession downloadTask didWriteDataUI 更新不适用于 urlSession downloadTask didWriteData
【发布时间】:2017-11-05 23:15:29
【问题描述】:

目前,我在使用下载任务时遇到了更新用户界面的问题。以下函数应该更新用户界面,但它有时会起作用。为什么每次下载文件都不起作用? NSLog的日志每次都显示在调试器中!

func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask, didWriteData bytesWritten: Int64, totalBytesWritten: Int64, totalBytesExpectedToWrite: Int64) {
  let curDownloadSize = totalBytesWritten / (1024*1024)
  let totalDownloadSize = totalBytesExpectedToWrite / (1024*1024)

  if curDownloadSize != oldDownloadSize {
    DispatchQueue.main.async {
      self.progressLabel!.text = "\(self.curDownloadSize)MB / \(self.totalDownloadSize)MB"
      self.progressView!.progress = Float(totalBytesWritten) / Float(totalBytesExpectedToWrite)
      NSLog("Download progress: \(Float(totalBytesWritten) / Float(totalBytesExpectedToWrite))");
    }
  }
}

progressLabelprogressView 目前都可用。

顺便说一句,我已经用同一个文件多次测试过,有时可以,有时不行。

更新:我读到过像这样使用第二个调度队列

DispatchQueue.global(qos: .utility).async {
  DispatchQueue.main.async {
    (same as above)
  }
}

但这有时也有效。

【问题讨论】:

  • 你不需要在该方法中使用 DispatchQueue
  • 好的,我之前尝试过,结果相同,但我相信它不像 DispatchQueue 那样经常工作。
  • 您是否同时进行多个下载?你只有一个标签。确保在开始新任务之前取消任何先前的会话任务。
  • 同样,该方法已经在主线程中调用/执行。不要在那里使用调度
  • 没有多次下载。同样,如果没有调度,也会出现同样的问题。

标签: swift user-interface dispatch urlsession


【解决方案1】:

最近,我解决了这个问题。

如果将太多事件推送到主队列,则会出现此问题。它只是在互联网连接非常好的情况下发生的。在这种情况下,回调被调用得太频繁了。

我的解决方案:

progressCounter += 1
if progressCounter % 30 == 0 {
  DispatchQueue.main.async {
    self.progressLabel!.text = "\(self.curDownloadSize)MB / \(self.totalDownloadSize)MB"
    self.progressView!.progress = Float(totalBytesWritten) / Float(totalBytesExpectedToWrite)
    NSLog("Download progress: \(Float(totalBytesWritten) / Float(totalBytesExpectedToWrite))");
  }
}

progressCounter之前已经初始化为0。

【讨论】:

    猜你喜欢
    • 2018-08-14
    • 1970-01-01
    • 2017-04-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多