简体   繁体   English

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

[英]Is calling UICollectionView.reloadData() bad practice? If so, why?

I worked with a brilliant developer once who more or less refused to ever call reloadData() on a UICollectionView . 我曾与一位出色的开发人员合作过,他或多或少拒绝在UICollectionView上调用reloadData()

He even frowned upon collectionView.reloadItemsAtIndexPaths(collectionView.indexPathsForVisibleItems()) , preferring instead to reload only the exact index paths that required a visual update. 他甚至对collectionView.reloadItemsAtIndexPaths(collectionView.indexPathsForVisibleItems())不满意,而是仅重新加载需要可视更新的精确索引路径。

I picked this up from him but am struggling to think of what problems specifically would be caused by a generic reloadData() . 我从他那里挑选了这个,但我很难想到通用reloadData()特别会导致什么问题。 Of course, if you have expensive side-effects that are triggered by a reload, that's one thing. 当然,如果你有重新加载触发的昂贵的副作用,这是一回事。 But if your data source itself is just hanging out, why not reloadData() as an easy-on-the-coding-side way of updating the collection view? 但是,如果您的数据源本身只是reloadData() ,那么为什么不将reloadData()作为一种简单的编码方式来更新集合视图呢?

What problems will be caused by this practice? 这种做法会带来什么问题?

No, it is not a bad practice at all. 不,这根本不是一个坏习惯。

Just a short overview, So you get your answer 只是一个简短的概述,所以你得到你的答案

UICollectionView is highly optimized, and thus only keep On-screen visible rows in memory. UICollectionView经过高度优化,因此只在内存中保留屏幕上可见的行。 Now, All rows Cells are cached in Pool and are reused and not regenerated. 现在,所有行单元格都缓存在池中并被重用而不是重新生成。 Whenever, user scrolls the UICollectionView, it adds the just-hidden rows in Pool and reuses them for next to be visible rows. 每当用户滚动UICollectionView时,它会在Pool中添加刚刚隐藏的行,并重新使用它们作为可见行。


So, when you call reloadData(), it simply updates the data in row cells, like updating the UILabel text and the update occurs only for visible cells, and the process goes on. 因此,当您调用reloadData()时,它只是更新行单元格中的数据,例如更新UILabel文本,并且仅针对可见单元格进行更新,并且该过程继续进行。

Now, Consider you have ten rows visible in your collection view and while calling 现在,假设您在集合视图中和调用时有十行可见

reloadItemsAtIndexPaths(collectionView.indexPathsForVisibleItems()) reloadItemsAtIndexPaths(collectionView.indexPathsForVisibleItems())

you simply update the UILabel like elements for only those items, but if you call reloadData(), you update the data for ten visible items, which doesn't make any difference as it is a very light process. 您只需更新UILabel类似于元素的元素,但如果您调用reloadData(),则更新十个可见项目的数据,这没有任何区别,因为它是一个非常轻的过程。

You should use reloadData() everywhere. 你应该在任何地方使用reloadData()。 Keep it simple and readable. 保持简单易读。 Performance wise, reloadItems doesn't make any difference. 性能方面,reloadItems没有任何区别。

It is properly elaborated in Apple Docx 它在Apple Docx中得到了详细阐述

Apple Link Apple Link

Call this method to reload all of the items in the collection view. 调用此方法可重新加载集合视图中的所有项目。 This causes the collection view to discard any currently visible items and redisplay them. 这会导致集合视图丢弃任何当前可见的项目并重新显示它们。 For efficiency, the collection view only displays those cells and supplementary views that are visible. 为了提高效率,集合视图仅显示可见的单元格和补充视图。 If the collection data shrinks as a result of the reload, the collection view adjusts its scrolling offsets accordingly. 如果集合数据由于重新加载而缩小,则集合视图会相应地调整其滚动偏移。

As a general refusal, I think it is exaggerated. 作为一般拒绝,我认为这是夸大其词。 There will be some performance gains if the table is large, and if the items are expensive to create. 如果表很大,并且如果项目的创建成本很高,则会有一些性能提升。 If the number of items per row can vary, and you reload item #317 out of 500 items, then you know that the number of items in all the previous rows hasn't change, so you don't need to recalculate that. 如果每行的项目数可能不同,并且您从500个项目中重新加载项目#317,那么您就知道前面所有行中的项目数没有变化,因此您无需重新计算。 But if you only have 20 items, it usually makes little difference. 但如果你只有20件物品,那通常没什么区别。

reloadData and reloadItemsAtIndexPaths will only cause to recreate and redisplay the cells for rows which have an associated visible cell. reloadDatareloadItemsAtIndexPaths将仅导致为具有关联的可见单元格的行重新创建和重新显示单元格。

So, since the number of visible cells are usually not changing and are usually small (eg 5 to 20 at max), the overall work to render cells is always constant and independent on the number of items in your data model. 所以,既然可见细胞的数量通常不发生变化,通常是 (例如,5至20最大),整体工作呈现细胞始终保持恒定 ,并独立于数据模型中的项目数。

As opposed to reloadItemsAtIndexPaths , which selectively re-renders the specified visible cells, reloadData will update all currently visible cells, and also update the underlying and associated views when the number of items of the model has changed (eg adjusting scrollbar and hight of the view). reloadItemsAtIndexPaths (有选择地重新呈现指定的可见单元格)相反, reloadData将更新所有当前可见的单元格,并在模型的项目数量发生更改时更新基础视图和关联视图(例如,调整滚动条和视图的高度) )。

You may use reloadItemsAtIndexPaths for performance reasons - but generally, it's not required - and oftentimes not recommended, since it requires to take care about the number of items at other places in your code, too. 出于性能原因,您可以使用reloadItemsAtIndexPaths - 但通常不需要 - 并且通常不建议这样做,因为它还需要关注代码中其他位置的项目数。

This is not just in the reload method in collectionView . 这不仅仅在collectionView中的reload方法中。 but the same issue with the Tableview . 但与Tableview相同的问题。 I don't know whether you are aware of reload method of tableview and collectionView .I am explaining overhear. 我不知道你是否知道tableviewcollectionView的重载方法。我正在解释无意中听到的。

When you call reload method. 当你调用reload方法时。 OS Check for all visible cell. 操作系统检查所有visible单元格。 and call cellForRow method for all cell. 并为所有单元cellForRow方法。 It means you code perform extra thing. 这意味着你的代码执行额外的事情。 which are unnecessary. 这是不必要的。 So it's perfect way to call reloadItemsAtIndexPaths to reload only those cell which need to update. 因此,调用reloadItemsAtIndexPaths仅重新加载需要更新的单元格是完美的方法。

Suppose you collectionView having 20 visible cell. 假设你的collectionView有20个可见单元格。 having image which is set at cellForRow Method. 具有在cellForRow方法中设置的图像。 now you want to update the image at cell 11. if you call reload method then cellForRow will call for each and every cell. 现在你想在单元格11更新图像。如果你调用reload方法,那么cellForRow将调用每个单元格。 But if you use reloadItemsAtIndexPaths and only one indexPath then it will only execute cellForRow once that is for cell 11. 但是如果你使用reloadItemsAtIndexPaths并且只使用一个indexPath那么它只会执行一次用于单元格11的cellForRow

It's just give you some performance gain. 它只是给你一些性能提升。 If you have a lot of items then for reloading a few items you don't have to reload the whole CollectionView. 如果你有很多项目然后重新加载一些项目,你不必重新加载整个CollectionView。 But if you have few items then it's not that costly. 但如果你的产品很少,那就不那么贵了。

The thing is that it's a small performance gain for a few items. 问题是,对于少数项目来说,这是一个很小的性能提升。 But it's a good practice. 但这是一个很好的做法。 So, choice is yours. 所以,选择是你的。

reloadData can be considered bad practice if it is called for every single small change in data. 如果为数据中的每一个小变化调用reloadData可能被认为是不好的做法。 When calling reloadData , cells are recreated, there is no guarantee that every visible data item will get the same cell after reloadData . 调用reloadData ,将重新创建单元格,不能保证每个可见数据项在reloadData之后都会获得相同的单元格。 In fact they will usually not. 实际上他们通常不会。 This means that if you have long running operations in your cells like animations or touch recognizers, they can create lot of hard traceable bugs if you don't understand what is happening. 这意味着如果您在单元格中长时间运行操作(如动画或触摸识别器),如果您不了解发生的情况,它们可能会产生大量难以追踪的错误。

Refreshing UITableView/UICollectionView view using reloadData is desirable when changing data collection to table. 在将数据收集更改为表时,需要使用reloadData刷新UITableView / UICollectionView视图。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 UICollectionView.reloadData()不会触发UICollectionDataSource方法 - UICollectionView.reloadData() do NOT trigger UICollectionDataSource methods UICollectionView.reloadData()更改单元格顺序| iOS Swift - UICollectionView.reloadData() changes cell order | iOS Swift UICollectionView.reloadData或UICollectionView.deleteItemsAtIndexPaths使单元格隐藏但仍可单击 - UICollectionView.reloadData or UICollectionView.deleteItemsAtIndexPaths makes cell hidden but still clickable UICollectionView.reloadData()在添加第一个项目后起作用,然后似乎在后面运行了一个 - UICollectionView.reloadData() works after adding first item, then seems to run one behind uicollectionview-数据自动加载而无需调用reloaddata - uicollectionview - data automatically load without calling reloaddata 为什么UICollectionView reloadData使我的应用程序崩溃? - Why is UICollectionView reloadData crashing my app? 使用 collectionView(_:layout:sizeForItemAt:) 调整 UICollectionView 单元格而不调用 reloadData() - Resizing UICollectionView cells with collectionView(_:layout:sizeForItemAt:) without calling reloadData() 在reloadData上禁用UICollectionView动画 - Disable UICollectionView animation on reloadData reloadData UICollectionView上的内存泄漏 - Memory leak on reloadData UICollectionView UICollectionView reloadData问题 - UICollectionView reloadData issue
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM