Ios -[UICollectionView\u endItemAnimations]崩溃中的断言失败

Ios -[UICollectionView\u endItemAnimations]崩溃中的断言失败,ios,objective-c,core-data,uicollectionview,nsfetchedresultscontroller,Ios,Objective C,Core Data,Uicollectionview,Nsfetchedresultscontroller,我正在我的应用程序中使用核心数据,它将存储下载的数据。当应用程序下载数据时,我会将这些数据保存在privateQueueContext(NSPrivateQueueConcurrencyType)中 一旦核心数据保存完成,我就应该更新UI。为了实现这一点,我定义了NSFetchedResultsController委托方法。正如我所料,当核心数据发生变化时,这些委托方法将被调用 在didChangeObject方法中,我插入了新的单元格,但当核心数据中插入了许多对象时,它会导致崩溃,并给出以下错

我正在我的应用程序中使用核心数据,它将存储下载的数据。当应用程序下载数据时,我会将这些数据保存在privateQueueContext(NSPrivateQueueConcurrencyType)中

一旦核心数据保存完成,我就应该更新UI。为了实现这一点,我定义了NSFetchedResultsController委托方法。正如我所料,当核心数据发生变化时,这些委托方法将被调用

didChangeObject
方法中,我插入了新的单元格,但当核心数据中插入了许多对象时,它会导致崩溃,并给出以下错误消息

***-[UICollectionView\u endItemAnimations]中的断言失败
CoreData:错误:严重的应用程序错误。在调用-controllerDidChangeContent:期间,从NSFetchedResultsController的委托捕获到异常。无效更新:节0中的项目数无效。更新(379)后现有节中包含的项目数必须等于更新(325)前该节中包含的项目数,加上或减去从该节插入或删除的项目数(插入52个,删除0个),加上或减去移入或移出该节的项目数(0移入,0移出)。具有userInfo(null)

我假设数据源在完成新的单元格插入动画之前发生了更改

我希望很多人都会遇到同样的问题,堆栈溢出中有很多类似的问题,但是没有一个答案对我来说是正确的。你能有人帮我解决这个问题吗

在核心数据中插入新对象

for (NSDictionary *obj in books){
    Book *book = [Book insertInManagedObjectContext:context];
    book.udid = [obj objectForKey:@“id”]  
}

[context performBlock:^{
   NSError *error = nil;
   if ([context save:&error]) {
        NSLog(@“success”);
   }                
}];
获取结果控制器委托

- (void)controllerWillChangeContent:(NSFetchedResultsController *)controller {
   self.blockOperation = [NSBlockOperation new];
  }

- (void)controller:(NSFetchedResultsController *)controller didChangeObject:(id)anObject atIndexPath:(NSIndexPath *)indexPath forChangeType:(NSFetchedResultsChangeType)type newIndexPath:(NSIndexPath *)newIndexPath {
   __weak UICollectionView *collectionView = self.collectionView;
   switch(type) {
      case NSFetchedResultsChangeInsert:{
           [self.blockOperation addExecutionBlock:^{
            [collectionView insertItemsAtIndexPaths:[NSArray arrayWithObject:[NSIndexPath indexPathForItem:newIndexPath.item + 1 inSection:newIndexPath.section]]];
           }];
           break;
      }
      default:
        break;
   }
}

- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller {
    [self.collectionView performBatchUpdates:^{
    [self.blockOperation start];
    } completion:nil];
  }

您的
performBlock
保存时间太长。您可以

  • 只需在主线程上保存即可。保存500本书需要一秒钟的时间,而且由于UI中没有发生任何重要事件(用户正在等待),因此无需在块中执行

  • 改为使用
    performBlockAndWait
    。只有在保存完成后才会更新表视图。用户的结果与在主线程上保存非常相似

  • 使用
    NSFetchedResultsControllerDelegate
    而不使用块操作。遵循Xcode提供的“获取结果”控制器模板。这可能比仅在主线程上保存要慢,因为UI将获得多个更新


您能包含完整的错误文本吗?通常在您包含的行之后会有额外的信息。@jrturton感谢您的回复***在-[UICollectionView\u endItemAnimations]中的断言失败,/SourceCache/UIKit_Sim/UIKit-3318.16.14/UICollectionView.m:3917CoreData:错误:严重的应用程序错误。在调用-controllerDidChangeContent.期间,从NSFetchedResultsController的委托捕获到异常。无效更新:节0中的项数无效。update(379)必须等于更新(325)之前该节中包含的项目数,加上或减去从该节插入或删除的项目数(52个插入,0个删除),加上或减去移入或移出该节的项目数(0个移入,0个移出)。带userInfo(null)