如何解决这个CollectionView崩溃?

我的应用程序有两个CollectionViewController 。 在给定的时间只有一个可见。

我在故事板上创build了以下结构:两个容器视图在彼此之上。 每个容器视图都有一个embedded的CollectionViewController 。 特定容器视图的可见性决定了哪个collectionViewController可见。

这就是问题。 两个CollectionViewController并行地接收数据,但是iOS有一个bug,如果一个CollectionViewController尝试在不可见的时候使用performBatchUpdates执行一个插入操作,那么这个bug会导致应用程序崩溃。

试图阻止这一点,我已经在两个CollectionViewController上创build了一个BOOL标志,以便他们可以知道它们是否可见并执行或者不是performBatchUpdates 。 就像是:

 if (self.isThisCollectionViewVisible == NO) return; [self.collectionView performBatchUpdates:^{ // bla bla... perform insert,m remove... 

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

我的意思是:让我们调用第一个CollectionViewControllerB调用第二个。 A是可见的,而B在这一点上是不可见的。 B开始接收数据,并试图执行一个performBatchUpdates但因为它是不可见的,所以if (self.isThisCollectionViewVisible == NO) return; 阻止performBatchUpdates运行,什么是好的。 现在我让A看不见, B看得见。 此时,标志self.isThisCollectionViewVisible被设置为YESperformBatchUpdates使应用程序崩溃,并显示以下错误:

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

我认为CollectionViewController实际上还没有准备好和更新,能够执行performBatchUpdates …这不是以前更新数据源,因为它正在更新的问题。

我可以做什么检查来防止这种情况发生?

注:我特别注意到这个崩溃有些奇怪的东西。 它说5个元素被插入,2个被删除,但实际上3个元素被插入,0个被删除,2个在发生崩溃时被改变。

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

似乎我并不孤单与我的解决scheme: http : //www.openradar.me/15262692

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

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

正如在苹果文档中所写的

在批量操作中插入之前处理删除。 这意味着在批处理操作之前,相对于集合视图状态的索引来处理删除的索引,并且在批处理操作中的所有删除之后相对于状态的索引来处理插入的索引。

所以,在插入之前移动这些变化就可以了!

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

  NSArray *selectedItemsIndexPaths = [self.collectionView indexPathsForSelectedItems]; 

有了这个:

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

我自己保持索引,现在没问题。 如果您已更新数据源,则不应将错误与数据源关联。 这可能与细胞的再利用有关。