使用延迟在 UITableViewCell 上延迟图像下载
Posted
技术标签:
【中文标题】使用延迟在 UITableViewCell 上延迟图像下载【英文标题】:Lazy image downloading on UITableViewCell using defer 【发布时间】:2016-09-12 07:58:00 【问题描述】:推迟一个单元格的异步图像下载是否安全?是否有意义?这背后的想法是我希望 URLSession.shared.image(...) 的回调函数在创建单元格后执行,并且只有一次调用 cellForRow(at: indexPath) 是有效的,因为我认为没有推迟这个方法此时应该返回 nil。
URLSession.shared.image 是一个私有扩展,它运行数据任务并仅在参数中提供的 url 有效且包含图像时才提供转义回调。
setImage(image:animated) 是一个私有扩展,允许您使用简单的动画在 UIImageView 中设置图像。
如果延迟不是办法,请指明替代方案。
感谢任何反馈,谢谢!
override func tableView(_ tableView: UITableView, cellForRowAt
indexPath: IndexPath) -> UITableViewCell
let cell = baseCell as! MyCell
let datum = data[indexPath.row]
cell.imageView.setImage(placeholderImage, for: .normal)
defer
URLSession.shared.image(with: datum.previewURL) image, isCached in
if let cell = tableView.cellForRow(at: indexPath) as? MyCell
cell.imageView.setImage(image, animated: !isCached)
return cell
【问题讨论】:
你是否为它尝试了 SDWebImage 第三方 【参考方案1】:NSHipster 有一篇关于如何/何时使用 defer 的好文章,here。
我不会以这种方式使用defer
。 defer 的目的是在一个代码块中清理/释放内存,而不是将其分散到多个退出点。
考虑在一个函数中使用多个保护语句,并且必须在每个函数中释放内存。
您不应该在事后简单地使用它来添加额外的代码。
正如@jagveer 所提到的,有许多第三方库已经这样做了,例如 SDWebImage 缓存。 AFNetworking 和 AlamoFire 也具有相同的内置功能。已经完成后无需重新发明***。
【讨论】:
【参考方案2】:在这种情况下,defer
无效。 defer
设置一个块以在范围退出时调用,您将立即执行此操作。
我认为您希望使用Dispatch
安排块在不同的线程中运行。你需要回到主线程来更新 UI。
由于这可能会在以后发生,因此您需要确保该单元格仍在用于相同的条目,并且在用户进一步滚动时没有被重复使用。如果它已被重用,那么再次获取单元格不是一个好主意,因为您最终会再次触发初始调用。我通常会在自定义 UITableViewCell
类中添加一些标识符以进行检查。
另外,您不是在创建单元格,而是从其他变量中获取它。如果有多个单元格,这可能是个问题。
override func tableView(_ tableView: UITableView, cellForRowAt
indexPath: IndexPath) -> UITableViewCell
let cell = tableView.dequeueReusableCell(withIdentifier: "base") as! MyCell
cell.row = indexPath.row
let datum = data[indexPath.row]
cell.imageView.setImage(placeholderImage, for: .normal)
DispatchQueue.global().async
// Runs in a background thread
URLSession.shared.image(with: datum.previewURL) image, isCached in
DispatchQueue.main.async
// Runs in the main thread; safe for updating the UI
// but check this cell is still being used for the same index path first!
if cell.row == indexPath.row
cell.imageView.setImage(image, animated: !isCached)
return cell
【讨论】:
以上是关于使用延迟在 UITableViewCell 上延迟图像下载的主要内容,如果未能解决你的问题,请参考以下文章
在 uitableviewcell 中激活 uislider 的延迟时间
如何从 UITableViewCell 中的自定义 UIButton 中删除触摸延迟
在 UITableView 中使用带有 [UIImage resizableImageWithCapInsets] 的 UIImageView 会导致延迟