在UITableView的单元格中下载图像的最佳实践? iOS版/斯威夫特

时间:2017-09-12 08:36:24

标签: ios swift uitableview concurrency uiimageview

所以我在工作中讨论了在UITableView的单元格中下载图像的更好方法。

这两个选项是: 在cellForRowAtIndex中,我异步下载图像,导致使用多个线程和多个网络请求,我们怀疑这可能是电池耗尽的问题。

另一个选择是使用一个线程和一个网络请求一次下载所有图像,方法是循环一个包含所有图像的数组。在cellForRowAtIndex之外的URL粗,然后调用表视图重载函数。

后一种方法也略有修改,我们可以在每次下载图像后立即设置每个图像(可能通过调用重新加载功能)。

所以我很想知道,处理这个问题的行业标准方法是什么?有什么优点和缺点,特别是在性能方面?有没有更好的方法?

2 个答案:

答案 0 :(得分:3)

我通常使用SDWebImage,它会缓存图像,以后可以重复使用。它提供了扩展和各种方法的灵活性。

检查我执行的代码:

import UIKit
import SDWebImage

extension AcceptedWinksViewController: UITableViewDataSource {
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: Constants.CellIdentifier.WinkListTableViewCell) as! WinkListTableViewCell
        let profile = self.winkList[indexPath.row] //Model
        let placeHolderImage = UIImage(named:"placeHolder") //your placeholder image, can be class or global variable
        if let url = profile.imageURL {
            cell.userImageView.sd_setImage(with: url, placeholderImage: placeHolderImage, options: .refreshCached, completed: nil) //check its various options
        }
        else {
            cell.userImageView.image = placeHolderImage
        }
        return cell
    }
}

答案 1 :(得分:0)

以下是我的最佳做法;

  • 如果您有大量的图像/单元,比如说1000,请不要全部下载。用户可能无法滚动到底部。仅下载可见的单元格。
  • 下载图像后,检查单元格是否仍然可见。 Tableview具有indexPathsForVisibleRows属性,您可以获取所有可见的单元格indexPaths。如果看不到单元格,则不应附加图像。
  • 您显然应该异步地在后台线程上下载它们。但是您应该限制最大并发操作数。您可以使用操作队列来执行此操作。否则,如果系统将创建大量线程(超过理想线程),则性能将变差。我不确定理想人数。只需尝试一些并比较结果即可。
  • 您应该缓存下载的图像,并且不应一次又一次地下载。只下载一次。您可以使用字典将它们缓存在内存中。
  • 下载图像后,将其附加到主线程上的单元格中。否则,如果您附加在后台线程上,则会变慢。
  • 您还可以实现取消机制。如果单元格不可见,则最好取消下载。这可以通过“操作”和“操作队列”来完成。使用GCD很难做到这一点。
  • 使用占位符图像,直到下载图像为止。

用于电池消耗;

根据Apple的能源效率指南,与逐个下载相比,批量下载项目更好。但是,这里需要进行一些尝试。我认为,与电池消耗相比,性能在这里具有最高的优先级。