如何解决此CollectionView崩溃问题?

时间:2016-03-31 12:59:16

标签: ios iphone uicollectionview performbatchupdates

我的应用有两个CollectionViewController个。在给定时间只能看到一个。

我在故事板上创建了以下结构:两个容器视图相互叠加。每个容器视图都嵌入了CollectionViewController。特定容器视图的可见性决定了哪个collectionViewController可见。

这就是问题所在。两个CollectionViewController都是并行接收数据,但iOS有一个错误,如果一个CollectionViewController在performBatchUpdates不可见的情况下尝试执行插入操作时会导致应用程序崩溃。

为了防止这种情况,我在CollectionViewController上创建了一个BOOL标志,这样他们就可以知道它们是否可见并执行与否performBatchUpdates。类似的东西:

if (self.isThisCollectionViewVisible == NO) return;

[self.collectionView performBatchUpdates:^{
   // bla bla... perform insert,m remove...

这解决了部分问题。但是应用程序在以下情况下继续崩溃:如果我点击按钮切换到不可见的CollectionViewController,使其在接收更新时可见。

我的意思是:让我们先调用A第一个CollectionViewControllerBA可见,此时B不可见。 B开始接收数据并尝试执行performBatchUpdates,但由于它不可见,if (self.isThisCollectionViewVisible == NO) return;阻止performBatchUpdates运行,没关系。现在,我将A置于不可见状态,B可见。此时,标记self.isThisCollectionViewVisible设置为YESperformBatchUpdates使应用程序崩溃并出现此错误:

  

*断言失败 - [CollectionView _endItemAnimationsWithInvalidationContext:tentativelyForReordering:],/ BuildRoot / Library / Cache / com.apple.xbs / Source / UIKit / UIKit-3512.60.7 / UICollectionView.m:4625   * 由于未捕获的异常终止应用' NSInternalInconsistencyException',原因:'无效更新:无效   第0节中的项目数。包含在项目中的项目数   更新后的现有部分(76)必须等于数量   更新前的该部分中包含的项目(70),加号或减号   从该部分插入或删除的项目数(插入5个,   2删除)并加上或减去移入或移出的项目数   该部分(0移入,0移出)。'

我认为CollectionViewController尚未准备好并已更新为能够执行performBatchUpdates ...这不是以前不更新数据源的问题,因为它正在更新

我可以采取哪些措施来防止这种情况发生?

注意:我特别注意到这次崩溃的一些奇怪之处。它说插入了5个元素,删除了2个,但实际上插入了3个元素,0个被删除,2个崩溃发生时更改了。

3 个答案:

答案 0 :(得分:17)

我添加self.collectionView.numberOfItemsInSection(0)修复了崩溃。 当项目不可见时,collectionView在插入项目时会出现问题。

好像我并不孤单,我的解决方案:http://www.openradar.me/15262692

答案 1 :(得分:3)

此崩溃告诉您,您没有更新数据源以进行收集。执行performBatchUpdates后,您需要更新dataSource(数组或字典)并重新加载集合视图数据。

无效更新:第0部分中的项目数无效。更新后现有部分中包含的项目数(76)必须等于更新前该部分中包含的项目数(70),或者减去从该部分插入或删除的项目数(插入5个,删除2个),加上或减去移入或移出该部分的项目数(0移入,0移出)。'

正如苹果文档中所述

  

在批处理操作中插入之前处理删除。这意味着   删除的索引是相对于索引处理的   批处理操作之前的集合视图的状态,以及   插入的索引相对于索引进行处理   在批处理操作中的所有删除之后的状态。

因此,在插入之前移动更改,这将是一招!

答案 2 :(得分:0)

今天遇到了同样的错误,对于我来说,在performBatchUpdates块中替换了这个:

  NSArray *selectedItemsIndexPaths = [self.collectionView indexPathsForSelectedItems];

用这个:

  NSIndexPath *selectedIndexPath = [NSIndexPath indexPathForRow:self.selectIndex inSection:0];
  NSArray *selectedItemsIndexPaths = @[selectedIndexPath];

自己维护索引,现在没关系。如果您已更新数据源,则错误不应与数据源相关联。它可能与细胞的重复使用有关。