今天遇到一个很奇怪的现象,我同事拿着他的手机测试说在使用UICollectionView的操作数据崩溃了,而我试了很多手机,模拟器都没出现过,于是直接拿着他的手机联调了一下,发现崩溃如下:
*** Assertion failure in -[UICollectionViewData invalidateItemsAtIndexPaths:], /BuildRoot/Library/Caches/com.apple.xbs/Sources/UIKit/UIKit-3600.6.22/UICollectionViewData.m:150
原来问题出在UICollectionView的刷新方法reloadData这里了,但是其他手机就是没有崩溃,查看了一下他的系统是iOS10.2.1,不知道是不是这个系统版本没兼容好的原因,我改成了刷新某个特定区或者特定行就不会崩溃了。具体原因暂不清楚
如下:
[self.collectionView reloadItemsAtIndexPaths:@[[NSIndexPathindexPathForRow:1 inSection:0]]];
或者
[self.collectionView reloadSections:[NSIndexSetindexSetWithIndex:0]];
==================
问题补充一下。发现不是reloadData的问题。后来在测试中,使用reloadSections也会出现问题。
跟踪了一下,发现在reloadData过程中,最后一个(也就是新增加)的一个cell没有调用layoutSubviews。因为是在layoutSubviews中改变custom cell的image和label的值,所以新增加的cell没有刷新。后来换成了在赋值过程中调用更新image和label的代码,这样无论reloadData和reloadSections都有效了,因为这样保证了加载数据的时候imageView和label都被调用。或者也可以在cellForRowAtIndexPath中调用[cell setNeedsLayout];去强制调用layoutSubviews,这样也达到更新的效果。
但是有点比较奇怪的是,之前的uitableview和uicollectionview自定义cell都是在layoutSubviews里面更新对应的控件,却没出现过问题。是不是iOS7以后,加载的机制发生变化了。这个有待进一步研究。
今天查找资料的时候,顺便收集了一个图表,图表清楚说明了会引起调用layoutSubviews的操作。(x表示被调用)