从磁盘快速加载UITableViewCell图像

时间:2017-07-18 19:18:34

标签: uitableview uikit

我正在建立一个国家/地区选择器UITableViewController,其中每个UITableViewCell都包含该国家/地区的UIImage标志。我尝试在主线程的UIImage中加载.xcassets中每个单元格的tableView(_:cellForRowAt:)对象,如下所示:

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

        let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
        let imageName = UIImage(named: "US.png")
        imageView?.image = UIImage(named: imageName)
        return cell
}

产生的FPS约为46。然后我异步尝试相同的操作:

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

            let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)

            DispatchQueue.main.async {
                let imageName = UIImage(named: "US.png")
                imageView?.image = UIImage(named: imageName)
            }

            return cell
    }

它将我的滚动FPS提高到~55,这并不可怕。但我认为可以进一步优化。

在高性能可滚动UITableView中从磁盘快速加载图像的最佳方法是什么?第三方图书馆?

1 个答案:

答案 0 :(得分:1)

您仍在主线程上加载,可能类似

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

    let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)

    DispatchQueue("Somequeue").async {
        let imageName = UIImage(named: "US.png")
        DispatchQueue.main.async {
            imageView?.image = UIImage(named: imageName)
        }
    }

    return cell
}

会快一点。图像从主线程加载,一旦加载,您将返回主线程以设置图像。但是,如果您快速滚动,此方法可能会导致一些奇怪的行为。如果旧图像在最新图像之后加载,则可能会重复使用该单元格并最终在单元格上设置错误的图像。

最好实现某种使用自己的DispatchQueue的队列机制,并知道如何取消或忽略旧请求。

重点是将图像加载远离主线程:)