【问题标题】:Cancel NSOperations based on position in TableView/CollectionVIew根据 TableView/CollectionVIew 中的位置取消 NSOperations
【发布时间】:2014-07-31 18:20:18
【问题描述】:

假设我有一个表格视图或集合视图。在单元格中,我需要加载某些内容(例如图像)。我可以从本地存储(如果它已保存在那里)或从 Internet 获取内容。无论哪种方式加载内容都需要一段时间(500 kB 图像)。

最好的方法是创建一个 NSOperation,它会在后台加载,然后在完成时调用一个委托。

但是假设用户进入表格视图/集合视图并且队列开始获取第一组内容(1-10)但随后用户快速滚动到最后(可见单元格 100-110)我应该怎么做做?开始下载操作发生在单元格出现时(cellForRowAtIndexPath),所以我需要等待所有内容下载,直到用户(现在位于 tableView 末尾)看到内容。 我尝试在每个单元格上创建一个队列并在 prepareForReuse 中取消它,但这会使应用程序崩溃。

无论如何,如果用户在 tableview 的某个部分并且内容正在下载,但尚未显示,并且进一步滚动导致下载被取消然后返回。然后他将需要重新下载图像的前半部分,这对于有限的数据计划来说并不好。

处理这种情况的最佳方法是什么?

【问题讨论】:

  • 首先我肯定会为一个 tableView 做缩略图而不是 500 kB 的图像。细胞有多大? iPhone 上一个正常大小的电池,你可以获得大约 6 个电池。你为什么要强迫他们只为一屏的行加载 3 MB 的数据?加载缩略图以加快速度。如果他们要去实际的屏幕细节,只提交更大的图像(500 kB)。
  • 这更多是理论上的讨论。当然,如果可能的话,我会为这样的应用程序使用缩略图。

标签: ios objective-c uitableview nsoperation


【解决方案1】:

您可以让您的控制器类采用UITableViewDelegate 协议,这将允许您将自定义代码注入–tableView:willDisplayCell:forRowAtIndexPath:(在要显示单元格时由表格视图调用)。在其中,您可以计算出,由于屏幕大小,只有 k 显示的任何行的索引内的行可能是可见的;因此,在此方法调用中,取消与该范围之外的行关联的所有加载操作(相对于indexPath 参数)。

【讨论】:

  • 这意味着取消下载操作队列并在添加“屏幕上”单元格的下载后立即?这不会导致某些操作在它们再次添加到队列之前被取消吗?我应该手动启动操作而不是使用操作队列吗?
  • 假设您在一个方向上连续滚动(我认为这是不可避免的),那么您就不会有这个问题。考虑:假设您从索引 0 开始,格式化为 indexPath,并且您一次只能在表上放置 5 行(我忘记了确切的数字)。这意味着当你向右滚动时,它会说“试图显示第 6 行”,所以会调用它;现在您指定任何方向超过 5 的所有内容都将停止下载:包括 1,这没关系,因为它正在从屏幕上移除;一切都> 11,这没关系,因为他们从未开始
  • @Quintana 老实说,我认为您应该只使用 NSDictionary 而不是跟踪 k 索引。您可以有多个 k,具体取决于是否引入了更多屏幕尺寸。你可以有一个 的 NSDictionary。如果您的操作返回,请将其从字典中删除。否则,在您的 didEndDisplayingCell 回调中,您可以取消该索引的操作。
  • @LyricalPanda 好点。虽然如果你这样做,不要忘记将@(IndexPath.row) 存储为字典键,因为IndexPath.row 返回一个 NSInteger,需要将其转换为 NSNumber 才能存储在字典中。可以使用-integerValue 检索其文字值。
猜你喜欢
  • 2020-03-19
  • 1970-01-01
  • 2021-07-15
  • 1970-01-01
  • 1970-01-01
  • 2019-04-19
  • 2016-12-12
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多