【问题标题】:Downloading images only for visible UITableViewCells仅为可见的 UITableViewCells 下载图像
【发布时间】:2014-08-27 19:51:07
【问题描述】:

UITableViewController 中,我有自定义单元格,其中包含我使用TMCache 缓存的缩略图。所以加载单元格的基本工作流程是:

  1. 用模型中的数据填充单元标签
  2. 检查我是否缓存了缩略图
  3. 如果是,则从缓存中获取...
  4. 如果没有,请从网上下载...

我担心的是,当我在缓存中没有任何内容时,我会开始下载大量图像(即使我设置了最大并发任务数),因此当用户滚动例如 100 行时,我的 @ AFHTTPSessionManager 中的 987654324@ 数组将处理所有这些,即使用户对其中许多都不感兴趣。

所以我提出了这个解决方案: 当用户向下滚动并开始下载时,但稍后此单元格会离开屏幕,我想取消此单元格的NSURLSessionDataTask。但是......我不知道如何检查哪个单元格应该取消其任务以及更重要的问题,如果任务在 90% 完成并且我取消它(浪费数据传输)怎么办?我注意到在 Facebook 应用程序中,它们并没有取消这些任务,因为当您向上滚动时它们已加载。

我想知道这是不是一个好方法,还是我试图让一切变得过于复杂?

【问题讨论】:

  • 可能的解决方案:为什么不将未完成请求的数量限制在 10 个左右。如果用户滚动浏览 10 个项目的速度比加载单个项目的速度快,那么他们可能不感兴趣。
  • 如果他们快速滚动到第 100 行怎么办?您将无法从单元格 1-10 加载图像,而用户将看到空单元格 #100。
  • @sha 他们不会被困在等待单元格 1-10 加载。一旦单元格 11 变得可见,它将取消单元格 1 的加载(如果它仍然未完成)。如果您快速滚动到第 100 行,它会立即开始加载它,您可能还没有完成加载您滚动过去的任何单元格。
  • @CrimsonChris 以及如何限制AFHTTPSessionManager 以适应您的解决方案?我不知道这是否可能!

标签: ios objective-c uitableview afnetworking


【解决方案1】:

查看UITableViewDelegate Protocol Reference

具体来说,您可以使用以下方法来跟踪单元格的出现和消失:

– tableView:willDisplayCell:forRowAtIndexPath:

- tableView:didEndDisplayingCell:forRowAtIndexPath:

【讨论】:

    【解决方案2】:

    为什么要浪费带宽?这样做:

    UITableViewControllerDataSource::cellForRowAtIndexPath: 中启动一个计时器,例如 200 毫秒或其他时间,它会在触发时开始下载过程。将计时器与 indexPath(或单元格)相关联。

    UITableViewControllerdelegate::tableView:didEndDisplayingCell::如果计时器还没有关闭,则终止它。

    【讨论】:

    • OP 提出了对终止几乎完成的连接的担忧。您如何看待在达到上限时保留开始被取消的未完成请求的列表?
    • 嗯。因此,如果用户快速滚动表格单元格 1-10,并最终查看第 11 个,第 11 个图像不会永远不会显示,因为它的请求达到了限制?
    • 如果达到上限,它将取消队列中最早的请求。这样,当新单元格变得可见时,它总是可以启动新请求。
    • 这也有效。如果您不想将请求数量与可见表格单元格的数量联系起来,这很有用。
    • 您可以调整数字以根据应用程序为您提供最佳性能。我很确定这就是 Facebook 等应用程序处理表格加载的方式。
    【解决方案3】:

    有一个 UITableViewCell 方法可以覆盖:prepareForReuse。当表格视图不再需要此单元格并为另一个可见的单元格重用内存时,它将被调用。

    我认为取消与此单元格关联的请求对您来说是一个好的开始。

    【讨论】:

    • 无法保证 prepareForReuse 何时会被调用,除非在它重新显示之前,afaik。
    • 使用 didEndDisplayingCell 会更安全。
    • 我想说的是——已经有基础设施可以重用与表格单元相关的资源。在任何人必须开始实施他们自己的之前 - 我建议研究现有的。
    • 我不这么认为。我认为依赖 didEndDisplaying 更复杂,可能没有必要。
    • 在返回缓存的单元格之前,您无法知道表格视图将创建多少个单元格,因此您实际上无法以可预测的方式依赖 prepareForReuse。使用 didEndDisplayingCell 是正确的。
    猜你喜欢
    • 1970-01-01
    • 2013-04-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多