2015-12-21 58 views
9

我已经读了很多的answers这里说,通过使用AlamofireImage辅助方法(如af_setImageWithURL())或任何同等库中,你不需要担心电池再利用的东西(另外,许多出版教程其实只是这样做)。也就是说,我不必保留对单元格的弱引用,也不必通过使用tableView的cellForRowAtIndexPath()方法在后台下载完成后更新其imageView,就像我们通常在手动请求时所做的那样。使用AlamofireImage里面的UITableViewCell

首先,这是真的吗?如果是这样,它是如何在库内完成的,因为我试图追踪AlamofireImage的af_setImageWithURL()代码,并且我找不到任何努力来确保我们仍在使用我们提出请求的单元格。我错过了什么吗?

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

+0

AlamofireImage不会自动避免细胞重复使用问题。 – dan

+0

所以你告诉我,所有这些教程都做错了,这真的很有趣!但是,现在它变得更有意义了...... – Mamouneyya

+0

我不确定你在说什么教程,但如果他们中的一些人做错了,我不会感到惊讶。 – dan

回答

14

假设你正在谈论UIImageView类别,是的,它确实解决了许多问题困扰着天真的异步图像检索问题,即:

  • 如果电池插入上面或下面的单元格在问题中,NSIndexPath已更改的事实不会影响所讨论单元的image的异步更新。

  • 如果您快速滚动到第100行,因为在重用单元上调用af_setImageWithURL,以前与此重用单元关联的先前行的请求将被取消。的这个

    • 一个含义是,它避免了对可见行得到与先前使用该重用小区相关联的行的图像的图像请求更新图像视图。 (这可以避免简单实现可能遇到的缓慢连接上的图像“闪烁”。)

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

  • AlamofireImage还提供图像缩放程序中,示出了用于细胞的缩略图图像时,这是很重要的。如果您不调整图像大小,如果使用大型资源(特别是在可以看到许多缩略图图像的收集视图中),则可能会产生过多的内存使用情况。

在该AlamofireImage可能不是正常,因为我们想处理UITableViewCell问题方面,它包括:

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

  • 关于预热(预取与可见行相邻的单元格的图像),AlamofireImage在这里没有太多的工作。您可能想要查看与可见行相邻的单元格的一些低优先级请求管理,以便可见单元格的性能不会受到负面影响,但也可以在用户滚动时与这些行关联的图像已经存在。

底线,这是一个夸张地说:“你不用担心电池再利用的东西”使用UIImageView类别时。您仍然需要仔细设计您的单元复用逻辑,例如:

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

但是这是事实,一个良好的执行UIImageView类别可以防止过于简单化的异步图像检索程序的许多陷阱。但它不是银弹。

+1

现在都清楚了。谢谢你的完美答案。 – Mamouneyya

+1

我发现AlamofireImage的UIImageView类别对UITableViewCells不起作用(至少不是开箱即可)。异步请求完成后,单元需要刷新,并且不会自动发生。我们可以在'setImageWithURL'的完成块中完成它,但是我们可以进入一个无限循环,重新获取图像(甚至从缓存中获取)并无限期地重复这个过程。如果有人找到了一个很好的解决方案,我很乐意听到它。 – elsurudo

+0

所有异步的'UIImageView'扩展都会受此影响。最简单的方法是使用固定的单元布局。如果您需要动态布局,那么是的,您需要刷新/重新加载单元格,但检查是否在启动另一个请求(例如指示图像是否已被检索的某个状态变量)之前检索了单元格。 – Rob

相关问题