调用UICollectionView.reloadData()是不是很糟糕?如果是这样,为什么?

时间:2016-02-18 08:40:16

标签: ios cocoa-touch uicollectionview

我曾与一位出色的开发人员合作过,他或多或少拒绝在reloadData()上致电UICollectionView

他甚至对collectionView.reloadItemsAtIndexPaths(collectionView.indexPathsForVisibleItems())感到不满,而宁愿只重新加载需要直观更新的确切索引路径。

我从他那里捡到了这个,但我正在努力想到通用reloadData()特别会导致什么问题。当然,如果您有重新加载触发的昂贵副作用,那就是一件事。但是,如果您的数据源本身只是悬而未决,那么为什么不reloadData()作为一种简单的编码方式来更新集合视图呢?

这种做法会导致什么问题?

6 个答案:

答案 0 :(得分:23)

不,这根本不是一个坏习惯。

只是一个简短的概述,所以你得到答案

UICollectionView经过高度优化,因此只在内存中保留屏幕上可见的行。现在,所有行单元格都缓存在池中并被重用而不是重新生成。 每当用户滚动UICollectionView时,它会在Pool中添加刚刚隐藏的行,并重新使用它们作为可见行。

因此,当您调用reloadData()时,它只是更新行单元格中的数据,例如更新UILabel文本,更新只发生在可见单元格中,并且该过程继续进行。

现在,假设您在集合视图中和调用

时有十行可见

reloadItemsAtIndexPaths(collectionView.indexPathsForVisibleItems())

您只需更新UILabel类似的元素, 但是如果你调用reloadData(),你就会更新十个可见项目的数据,这没有任何区别,因为它是一个非常轻的过程。

你应该在任何地方使用reloadData()。保持简单易读。性能方面,reloadItems没有任何区别。

Apple Docx中已经详细阐述了

Apple Link

  

调用此方法重新加载集合视图中的所有项目。   这会导致集合视图丢弃任何当前可见的项目   并重新显示它们。为了提高效率,仅显示集合视图   那些细胞和可见的补充观点。如果   集合数据由于重新加载而收缩,即集合视图   相应地调整其滚动偏移。

答案 1 :(得分:1)

作为一般拒绝,我认为这是夸大其词。如果表很大,并且如果项目的创建成本很高,则会有一些性能提升。如果每行的项目数量可能会有所不同,并且您从500个项目中重新加载项目#317,那么您就知道之前所有行中的项目数量都没有变化,因此您不需要重新计算。但如果你只有20件物品,那通常没什么区别。

答案 2 :(得分:1)

reloadItemsAtIndexPathsreloadItemsAtIndexPaths只会导致重新创建并重新显示具有关联可见单元格的行的单元格。

因此,由于可见单元格的数字通常不会改变,并且通常(例如最多5到20),渲染单元格的整体工作总是如此常量,与数据模型中的项目数无关。

与选择性重新渲染指定的可见单元格的reloadData相反,reloadItemsAtIndexPaths将更新所有当前可见的单元格,并在模型的项目数量时更新基础和关联的视图已更改(例如,调整滚动条和视图的高度)。

代码中的其他地方也是。

答案 3 :(得分:0)

这不仅仅是collectionView中的重新加载方法。但与Tableview相同的问题。我不知道您是否了解tableviewcollectionView的重新加载方法。我正在解释听到的问题。

当您拨打reload方法时。操作系统检查所有visible单元格。并为所有单元格调用cellForRow方法。这意味着你的代码执行额外的事情。这是不必要的。因此,这是调用reloadItemsAtIndexPaths仅重新加载需要更新的单元格的完美方式。

假设您collectionView有20个可见单元格。具有设置为cellForRow方法的图像。现在你想在单元格11更新图像。如果你调用重载方法,那么cellForRow将调用每个单元格。但是,如果您使用reloadItemsAtIndexPaths且只使用一个indexPath,那么它只会在针对单元格11执行cellForRow

答案 4 :(得分:0)

这只会给你一些性能提升。如果你有很多项目然后重新加载一些项目,你不必重新加载整个CollectionView。但如果你的物品很少,那就不那么贵了。

事情是,对于少数项目来说,这是一个很小的性能提升。但这是一个很好的做法。所以,选择是你的。

答案 5 :(得分:0)

如果对每一个小的数据更改都调用

reloadData,则可以认为它是不当行为。调用reloadData时,将重新创建单元格,不能保证每个可见数据项在reloadData之后都将获得相同的单元格。实际上,它们通常不会。这意味着,如果您在诸如动画或触摸识别器之类的单元中进行长时间运行的操作,那么如果您不了解正在发生的事情,它们可能会创建许多难以追溯的错误。

将数据收集更改为表时,最好使用reloadData刷新UITableView / UICollectionView视图。