我一直在对UICollectionView的性能进行大量研究。结论很简单,对于大量单元格的性能较差。
编辑:抱歉,我重新阅读了您的帖子,您拥有的单元格数量应该没问题(请参见我的其他评论),因此单元格复杂性也可能是一个问题。
如果您的设计支持,请检查:
每个单元格都是不透明的。
单元格内容剪切到边界。
单元格坐标位置不包含小数值(例如始终计算为整个像素)
尽量避免重叠单元格。
尽量避免投影阴影。
原因其实很简单。很多人不理解这一点,但值得理解的是:UIScrollView没有使用核心动画来滚动。我天真地认为它们涉及某些秘密滚动动画“酱汁”,并且偶尔从代理那里请求更新以检查状态。但事实上,滚动视图只是一个类,它应用了一个数学函数来抽象UIView的坐标放置,因此视图的坐标被视为相对于一个抽象的contentView平面而不是相对于包含视图的原点。滚动视图将根据用户输入(例如滑动)更新抽象滚动平面的位置,并且当然还有物理算法,可以给转换后的坐标位置带来“动量”。
现在,如果您要制作自己的集合视图布局对象,在理论上,您可以产生一个完全颠倒底层滚动视图应用的数学翻译的集合视图布局对象。这很有趣但没用,因为它看起来似乎单元格根本没有移动,而您只是在滑动。但我提出这种可能性是因为它说明了集合视图布局对象与集合视图对象本身一起工作时执行了与底层滚动视图非常相似的操作。例如,它只是提供了一个机会,通过逐帧翻译要显示的视图的属性来应用额外的数学框架,通常这只是位置属性的翻译。
只有在插入、删除、移动或重新加载新单元格时才涉及核心动画;最常见的方法是调用:
- (void)performBatchUpdates:(void (^)(void))updates
completion:(void (^)(BOOL finished))completion
UICollectionView为滚动的每个帧和每个可见视图请求单元格布局属性,并且每个帧为每个视图布局。UIView是优化灵活性而不是性能的丰富对象。每次布局时,系统会执行一些测试来检查其alpha、zIndex、子视图、剪贴等属性。清单很长。这些检查以及对视图所做的任何更改都将为每个集合视图项的每个框架进行。
为确保良好的性能,所有逐帧操作都需要在17ms内完成。[由于您拥有的单元格数量,这根本不可能发生]用括号括起来,因为我重新阅读了您的帖子,意识到我误读了它。由于您拥有的单元格数量,不应该存在性能问题。我个人发现,在iPad 3上进行简化测试,只包含单个缓存图像的原始单元格,在屏幕上显示约784个单元格后,性能开始下降至50fps以下。
实际上,您需要让它少于这个数字。
就我个人而言,我正在使用自己的自定义布局对象,需要比UICollectionView提供的更高的性能。不幸的是,直到开发路径的某个地方,我才运行了上述简单测试,并意识到存在性能问题。我要重新制作UICollectionView的开源后移版本PSTCollectionView。我认为可以实现一个解决方法,以便每个单元格项的图层在一般滚动时都是使用操作编写的,从而绕过了每个UIView单元格的布局。这对我来说是有效的,因为我有自己的布局对象,我知道何时需要布局,并且我有一个巧妙的技巧,可以在此时让PSTCollectionView回退到其正常的操作模式。我已经检查了调用顺序,它看起来并不太复杂,也不完全不可行。但是肯定是非平凡的,必须进行进一步的测试,然后我才能确认它是否有效。