ios - swift:在后台加载图像数据
问题描述
我需要在单元格中加载 100 张图像。如果我在 tableView cellForRowAt 中使用此方法:
cell.cardImageView.image = UIImage(named: "\(indexPath.row + 1).jpg")
并开始快速滚动我的tableView
冻结。
我使用这种方法在后台加载修复冻结的图像数据:
func loadImageAsync(imageName: String, completion: @escaping (UIImage) -> ()) {
DispatchQueue.global(qos: .userInteractive).async {
guard let image = UIImage(named: imageName) else {return}
DispatchQueue.main.async {
completion(image)
}
}
}
称之为tableView cellForRowAt
:
loadImageAsync(imageName: "\(indexPath.row + 1).jpg") { (image) in
cell.cardImageView.image = image
}
但是我在这种方法中可能会出现一个错误,这样在快速滚动时我可能会看到一段时间的旧图像。如何修复这个错误?
解决方案
您的细胞正在被重复使用。
当单元格离开屏幕时,它会进入内部UITableView
的重用池,当您dequeueReusableCell(withIdentifier:for:)
进入时,tableView(_:cellForRowAt:)
您会再次获得此单元格(请参阅名称中的“可重用”)。UITableViewCell
了解的生命周期很重要。UITableView
不能UITableViewCell
为 100 行保留 100 living s,这会降低性能并很快让应用程序没有内存。
为什么你会在你的细胞中看到旧图像? 同样,单元格正在被重用,重用后它们保持旧状态,您需要重置图像,它们不会自行重置。您可以在配置新单元格时执行此操作,或检测单元格何时将被重用。
很简单:
cell.cardImageView.image = nil // reset image
loadImageAsync(imageName: "\(indexPath.row + 1).jpg") { (image) in
cell.cardImageView.image = image
}
另一种方法是检测重用和重置。在您的单元子类中:
override func prepareForReuse() {
super.prepareForReuse()
self.cardImageView.image = nil // reset
}
为什么您在细胞中看到错误的图像?到时completion
闭包将图像设置为cardImageView
,UITableViewCell
已被重用(甚至可能不止一次)。为防止这种情况,您可以测试是否在同一单元格中设置图像,例如,将图像名称与您的单元格一起存储,然后:
// naive approach
let imageName = "\(indexPath.row + 1).jpg"
cell.imageName = imageName
loadImageAsync(imageName: imageName) { (image) in
guard cell.imageName == imageName else { return }
cell.cardImageView.image = image
}
在设计列表时需要注意很多事情,我不会在这里详细介绍。我建议尝试上述方法并调查网络如何处理列表的性能问题。
推荐阅读
- node.js - NodeJS MongoDB UNIX 套接字连接
- parse-server - 降级解析服务器
- java - TreeTableView CheckBoxTreeTableCell 中的 ChangeListener 每次单击都会触发多次
- angular6 - HttpErrorResponse 中的 Error 对象的类型是什么
- binding - Xamarin Binding Android 将 [Activity] 属性添加到生成的类
- z3 - Z3:我应该使用 Arrays、IntVectors 还是其他东西?
- graph - 图表在 y 轴上展平
- r - 问:在 R 中的单个图中显示分组和组合的箱线图
- oracle - 合并记录,除一列外,每一列都是相同的数据
- javascript - 带有条件 JavaScript 的在线表单?