【问题标题】:Using AlamofireImage Inside UITableViewCell在 UITableViewCell 中使用 AlamofireImage
【发布时间】:2023-03-16 14:05:02
【问题描述】:

我在这里阅读了很多 answers 说通过使用 AlamofireImage 辅助方法(例如 af_setImageWithURL())或任何等效库,您无需担心单元重用的东西(另外,许多已发布的教程实际上只是这样做)。也就是说,在后台下载完成后,我不必保持对单元格的弱引用或使用tableView的cellForRowAtIndexPath()方法更新其imageView,就像我们通常手动请求时所做的那样。

首先,这是真的吗?如果是这样,它是如何在库中完成的,因为我试图追踪 AlamofireImage 的 af_setImageWithURL() 代码,但我找不到任何努力来确保我们仍在处理我们发出请求的同一个单元格。我错过了什么吗?

如果这听起来很愚蠢,我很抱歉,但我真的很困惑。

【问题讨论】:

  • AlamofireImage 不会自动避免单元重用问题。
  • 所以你告诉我所有这些教程都做错了,这真的很有趣!但是,是的,现在它更有意义了......
  • 好吧,我不确定你在说什么教程,但如果其中一些做错了,我不会感到惊讶。

标签: ios swift uitableview alamofireimage


【解决方案1】:

假设您谈论的是UIImageView 类别,是的,它确实解决了许多困扰幼稚异步图像检索问题的问题,即:

  • 如果在相关单元格的上方或下方插入单元格,NSIndexPath 已更改的事实不会影响相关单元格的 image 的异步更新。

  • 如果您快速滚动到第 100 行,当您在重复使用的单元格上调用 af_setImageWithURL 时,对先前与此重复使用的单元格关联的先前行的请求将被取消。

    • 这样做的一个含义是,它避免了可见行的图像视图随着对先前与此重用单元关联的行的图像的图像请求而更新。 (这避免了简单实现可能遇到的慢速连接上的图像“闪烁”。)

    • 这样做的另一个含义是,它避免了与单元格 100 关联的图像可能会积压在第 1-99 行的图像请求之后的性能问题。

  • AlamofireImage 还提供图像大小调整例程,这在显示单元格的缩略图时很重要。如果您不调整图像大小,则在使用大型资源时(尤其是在可能会显示许多缩略图的集合视图中)可能会占用大量内存。

就 AlamofireImage 可能无法像我们希望的那样优雅处理的UITableViewCell 问题而言,它包括:

  • 关于缓存,AlamofireImage 依赖于底层的NSURLCache,而不是通过NSCache 或本地持久存储进行自己的缓存。虽然我理解作者为什么这样做(有一定的直观吸引力,只要NSURLCache 应该 能够优雅地做到这一点),你应该知道NSURLCache 可能是有问题的,只有缓存根据记录不充分的规则(如果资源超过总缓存大小的 5%,则不会缓存;如果 HTTP 标头不完全正确,则不会缓存,等等)。所以必须小心缓存问题。

  • 关于预热(预取与可见行相邻的单元格的图像),AlamofireImage 在这里做的不多。您可能希望看到与可见行相邻的单元格的一些低优先级请求管理,这样可见单元格的性能不会受到不利影响,而且当用户滚动时与这些行关联的图像已经存在。

归根结底,在使用UIImageView 类别时说“您无需担心单元格重复使用的东西”是言过其实的。您仍然需要仔细设计您的单元重用逻辑,例如:

  • 确保没有任何路径绕过图像视图的更新,即使相关行可能没有要显示的图像;
  • 确定是否需要调整图像大小;
  • 确认NSURLCache 在您的情况下正确缓存;
  • 决定是否要创建和缓存缩略图;
  • 等。

但确实,一个执行良好的UIImageView 类别可以避免许多过于简单的异步图像检索例程的陷阱。但这不是灵丹妙药。

【讨论】:

  • 现在一切都清楚了。感谢您的完美回答。
  • 我发现 AlamofireImage 的 UIImageView 类别不适用于 UITableViewCells(至少,不是开箱即用的)。异步请求完成后,需要刷新单元格,这不会自动发生。我们可以在 setImageWithURL 的完成块中执行此操作,但随后我们可以进入无限循环,重新获取图像(甚至从缓存中)并无限期地重复该过程。如果有人找到了一个好的解决方案,我很乐意听到。
  • 所有异步的UIImageView 扩展都会受到这个影响。最简单的方法是使用固定的单元格布局。如果您需要动态布局,那么是的,您需要刷新/重新加载单元格,但在启动另一个请求之前检查您是否已经检索了单元格(例如,指示图像是否已被检索的某些状态变量)。
猜你喜欢
  • 2016-03-06
  • 2018-02-26
  • 1970-01-01
  • 1970-01-01
  • 2017-01-19
  • 2018-09-21
  • 2016-08-10
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多