【问题标题】:A table with cells that all have their own progress views is very slow包含所有具有自己进度视图的单元格的表格非常慢
【发布时间】:2016-06-25 15:59:16
【问题描述】:

我有一个表格,其中显示有关正在下载的对象列表的信息。每个单元格都包含一个UIProgressView,它会根据下载的进度进行更新。我的问题是,在这个进度视图的下载和更新过程中,一切都很慢,在Xcode的debug navigator中监控CPU是100%以上。

每个对象都存储有自己的进度属性。

class Download {
    var id: String = ""
    var progress: Float = 0
}

我有一个数组:

var downloads = [Download]()

在我的视图控制器中使用cellForRowAtIndexPath: 将其设置为tableView,使用类似于:

let download = downloads[indexPath.row]
cell.progressView.progress = download.progress 

我正在使用Alamofire 管理我的下载并使用包含的进度关闭,我正在更新下载的进度:

download.progress = Float(bytesRead) / Float(bytesExpected)

dispatch_async(dispatch_get_main_queue()) {
    self.tableView.reloadData()
}

在这一点上,我认为由于发生了大量更新,瓶颈正在发生。为了尝试限制问题,我尝试在更改时仅更新单个单元格:

let rowIndex = self.downloads.indexOf() { $0.id == download.id }                 
let indexPath = NSIndexPath(forRow: rowIndex!, inSection: 0)

dispatch_async(dispatch_get_main_queue()) {
    self.tableView.reloadRowsAtIndexPaths([indexPath], withRowAnimation: .None)
}

但是我发现这会导致一切变得更慢。

任何建议将不胜感激,在此先感谢您!

【问题讨论】:

  • 问题是你正在重新加载整个表格视图,而不是仅仅更新 UIProgressView。

标签: ios swift uitableview alamofire uiprogressview


【解决方案1】:

上传进度块每秒可以触发多次,重新加载整个表格视图代价高昂,效率低下。您应该做的是分别监控每个表格视图单元格中的上传进度。这是你可以做到的。 在您的 tableviewcell 中:

  var progressTimer: NSTimer?

  var download: Download? {
    didSet {
      guard let download = download else {
        // cancel your timer here
        return
      }
      // start NSTimer here to update UIProgressView every second
    }
  }

  func prepareForReuse() {
    super.prepareForReuse()
    download = nil
  }

在您的视图控制器中:

override func tableView(tableView: UITableView, willDisplayCell cell: UITableViewCell,
    forRowAtIndexPath indexPath: NSIndexPath) {
      cell.download = downloads[indexPath.row]
  }

【讨论】:

  • 谢谢!确实减少了负载,仍然有点慢,但我确信这是由于应用程序中发生的所有其他事情:\
  • 很高兴有帮助。您可以使用时间分析器来确定是什么减慢了应用程序的速度。或者只是注释掉一些代码,看看应用程序的行为方式。例如,注释掉“cell.download = downloads[indexPath.row]”,使单元格停止跟踪任何进度,然后测试响应能力。
【解决方案2】:

您正在尝试在进度更新时重新加载表格或单元格,这很繁重。

由于progressViews已经创建好了,尝试复用它们,你可以使用Tag获取progressView实例:

    let rowIndex = self.downloads.indexOf() { $0.id == download.id }
    let indexPath = NSIndexPath(forRow: rowIndex, inSection: 0)


    let cell = tableView.cellForRowAtIndexPath(indexPath)

    let progressView = cell?.viewWithTag(100) // Tag your progressView as 100

    progressView.progress = download.progress

更进一步,您还可以通过仅每 0.5 秒或更短的时间更新进度来调整性能,只要用户感觉顺利即可。但不是每一个progressChanged,那都太频繁了。

【讨论】:

    猜你喜欢
    • 2018-05-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-12-26
    • 2018-12-23
    相关资源
    最近更新 更多