在 UITableViewCell 中使用 AlamofireImage

Using AlamofireImage Inside UITableViewCell

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

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

对不起,如果听起来很愚蠢,但我真的很困惑。

假设您在谈论 UIImageView 类别,是的,它确实解决了一些困扰天真的异步图像检索问题的问题,即:

  • 如果一个单元格被插入到有问题的单元格的上方或下方,NSIndexPath已经改变的事实不会影响该单元格的image的异步更新有问题。

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

    • 其中的一个含义是,它避免了可见行的图像视图随着对先前与此重用单元格相关联的行的图像的图像请求而更新。 (这避免了简单实施可能遇到的慢速连接上的图像 "flickering"。)

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

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

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

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

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

最重要的是,在使用 UIImageView 类别时说 "you don't need to worry about cell reusing stuff" 是夸大其词。您仍然需要仔细设计您的单元重用逻辑,例如:

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

但是 well-executed UIImageView 类别确实可以预防 overly-simplistic 异步图像检索例程的许多陷阱。但这不是灵丹妙药。