![](/img/trans.png)
[英]UICollectionView.reloadData() do NOT trigger UICollectionDataSource methods
[英]Is calling UICollectionView.reloadData() bad practice? If so, why?
我曾与一位出色的开发人员合作过,他或多或少拒绝在UICollectionView
上调用reloadData()
。
他甚至对collectionView.reloadItemsAtIndexPaths(collectionView.indexPathsForVisibleItems())
不满意,而是仅重新加载需要可视更新的精确索引路径。
我从他那里挑选了这个,但我很难想到通用reloadData()
特别会导致什么问题。 当然,如果你有重新加载触发的昂贵的副作用,这是一回事。 但是,如果您的数据源本身只是reloadData()
,那么为什么不将reloadData()
作为一种简单的编码方式来更新集合视图呢?
这种做法会带来什么问题?
不,这根本不是一个坏习惯。
只是一个简短的概述,所以你得到你的答案
UICollectionView经过高度优化,因此只在内存中保留屏幕上可见的行。 现在,所有行单元格都缓存在池中并被重用而不是重新生成。 每当用户滚动UICollectionView时,它会在Pool中添加刚刚隐藏的行,并重新使用它们作为可见行。
因此,当您调用reloadData()时,它只是更新行单元格中的数据,例如更新UILabel文本,并且仅针对可见单元格进行更新,并且该过程继续进行。
现在,假设您在集合视图中和调用时有十行可见
reloadItemsAtIndexPaths(collectionView.indexPathsForVisibleItems())
您只需更新UILabel类似于元素的元素,但如果您调用reloadData(),则更新十个可见项目的数据,这没有任何区别,因为它是一个非常轻的过程。
你应该在任何地方使用reloadData()。 保持简单易读。 性能方面,reloadItems没有任何区别。
它在Apple Docx中得到了详细阐述
调用此方法可重新加载集合视图中的所有项目。 这会导致集合视图丢弃任何当前可见的项目并重新显示它们。 为了提高效率,集合视图仅显示可见的单元格和补充视图。 如果集合数据由于重新加载而缩小,则集合视图会相应地调整其滚动偏移。
作为一般拒绝,我认为这是夸大其词。 如果表很大,并且如果项目的创建成本很高,则会有一些性能提升。 如果每行的项目数可能不同,并且您从500个项目中重新加载项目#317,那么您就知道前面所有行中的项目数没有变化,因此您无需重新计算。 但如果你只有20件物品,那通常没什么区别。
reloadData
和reloadItemsAtIndexPaths
将仅导致为具有关联的可见单元格的行重新创建和重新显示单元格。
所以,既然可见细胞的数量通常不发生变化,通常是小 (例如,5至20最大),整体工作呈现细胞始终保持恒定 ,并独立于数据模型中的项目数。
与reloadItemsAtIndexPaths
(有选择地重新呈现指定的可见单元格)相反, reloadData
将更新所有当前可见的单元格,并在模型的项目数量发生更改时更新基础视图和关联视图(例如,调整滚动条和视图的高度) )。
出于性能原因,您可以使用reloadItemsAtIndexPaths
- 但通常不需要 - 并且通常不建议这样做,因为它还需要关注代码中其他位置的项目数。
这不仅仅在collectionView
中的reload方法中。 但与Tableview
相同的问题。 我不知道你是否知道tableview
和collectionView
的重载方法。我正在解释无意中听到的。
当你调用reload
方法时。 操作系统检查所有visible
单元格。 并为所有单元cellForRow
方法。 这意味着你的代码执行额外的事情。 这是不必要的。 因此,调用reloadItemsAtIndexPaths
仅重新加载需要更新的单元格是完美的方法。
假设你的collectionView
有20个可见单元格。 具有在cellForRow
方法中设置的图像。 现在你想在单元格11更新图像。如果你调用reload方法,那么cellForRow
将调用每个单元格。 但是如果你使用reloadItemsAtIndexPaths
并且只使用一个indexPath
那么它只会执行一次用于单元格11的cellForRow
。
它只是给你一些性能提升。 如果你有很多项目然后重新加载一些项目,你不必重新加载整个CollectionView。 但如果你的产品很少,那就不那么贵了。
问题是,对于少数项目来说,这是一个很小的性能提升。 但这是一个很好的做法。 所以,选择是你的。
如果为数据中的每一个小变化调用reloadData
可能被认为是不好的做法。 调用reloadData
,将重新创建单元格,不能保证每个可见数据项在reloadData
之后都会获得相同的单元格。 实际上他们通常不会。 这意味着如果您在单元格中长时间运行操作(如动画或触摸识别器),如果您不了解发生的情况,它们可能会产生大量难以追踪的错误。
在将数据收集更改为表时,需要使用reloadData
刷新UITableView / UICollectionView视图。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.