UICollectionView 在插入或删除很多项目时很慢 [英] UICollectionView is very slow when inserting or deleting many items

查看:29
本文介绍了UICollectionView 在插入或删除很多项目时很慢的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试从集合视图中插入和删除大量项目(例如 20,000 个),该操作需要很长时间.

I'm trying to insert and delete a large amount of items (say, 20,000) from a collection view, and the operation takes a very long time.

我创建的测试夹具由以下部分组成:

The test fixture I created is composed of the following:

  • UICollectionView 除了数据源外没有任何配置.
  • 默认UICollectionViewFlowLayout.
  • 根据 BOOL 变量返回 10K 或 30K 项的数据源.
  • 用于切换该变量的按钮.当设置为 YES 时,将 20K 项添加到数据源(只需更改 numberOfItemsInSection:)和具有 20K 项的 insertItemsAtIndexPaths:.当设置为 NO 时,deleteItemsAtIndexPaths: 会调用 20K 项.
  • 数据源中的单元配置除了将默认的 UICollectionViewCell 出列并返回它之外,什么都不做.
  • UICollectionView with no configuration besides a data source.
  • Default UICollectionViewFlowLayout.
  • Data source that returns either 10K or 30K items depending on a BOOL variable.
  • Button to toggle that variable. When set to YES, 20K items are being added to the data source (just by changing numberOfItemsInSection:) and insertItemsAtIndexPaths: with 20K items. When set to NO, deleteItemsAtIndexPaths: is called with 20K items.
  • Cell configuration in the data source does nothing besides dequeuing a default UICollectionViewCell and returning it.

在模拟器上运行它,它应该比任何设备都快,产生以下时间:

Running this on simulator, which should be faster than any device, yields the following timings:

  • 插入 20K 项:220 毫秒.
  • 删除相同的 20K 项:1100 毫秒.

这无论如何都非常慢,尤其是在主线程上执行时.

This is, by all means, horribly slow, especially when performed on the main thread.

这是来自instruments的截图,显示了UICollectionView内部实现中的热点(特别是_computeItemUpdates):

Here's a screenshot from instruments, showing the hotspots in UICollectionView's internal implementation (specifically, _computeItemUpdates):

我注意到使用 reloadData 而不是插入或更新项目要快得多(约 20 毫秒),可能是因为没有触发动画,因此无需计算每个项目的位置用于动画目的的项目和部分.

I've noticed that the use of reloadData instead of inserting or updating the items is way faster (~20ms), probably because no animations are triggered so there's no need to compute the position of each item and section for animation purposes.

任何有关如何克服此问题的想法将不胜感激.

Any ideas on how to overcome this would be appreciated.

推荐答案

展开 _computeItemUpdates.如果它调用的任何东西是你的,那么是的,你可以.

Expand _computeItemUpdates. If anything it's calling is yours, then yes you can.

一个例子是,如果您使用自定义布局,您可以要求它计算后台线程上的新位置,然后在该操作完成时调用插入/删除.

An example would be if you are using a custom layout, you could ask it to calculate the new positions on a background thread and then call insert/delete when that operation finishes.

你也可以很聪明,只为当前可见的范围调用插入/删除,然后在重新排列动画完成后你可以 reloadData 并且它看起来应该与用户没有太大区别透视.

You could also be smart about it and only call insert/delete for ranges that are currently visible, then after the rearrange animation finishes you could reloadData and it shouldn't look too different from a users perspective.

这篇关于UICollectionView 在插入或删除很多项目时很慢的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆