Ios -[UICollectionView\u endItemAnimations]崩溃中的断言失败
我正在我的应用程序中使用核心数据,它将存储下载的数据。当应用程序下载数据时,我会将这些数据保存在privateQueueContext(NSPrivateQueueConcurrencyType)中 一旦核心数据保存完成,我就应该更新UI。为了实现这一点,我定义了NSFetchedResultsController委托方法。正如我所料,当核心数据发生变化时,这些委托方法将被调用 在Ios -[UICollectionView\u endItemAnimations]崩溃中的断言失败,ios,objective-c,core-data,uicollectionview,nsfetchedresultscontroller,Ios,Objective C,Core Data,Uicollectionview,Nsfetchedresultscontroller,我正在我的应用程序中使用核心数据,它将存储下载的数据。当应用程序下载数据时,我会将这些数据保存在privateQueueContext(NSPrivateQueueConcurrencyType)中 一旦核心数据保存完成,我就应该更新UI。为了实现这一点,我定义了NSFetchedResultsController委托方法。正如我所料,当核心数据发生变化时,这些委托方法将被调用 在didChangeObject方法中,我插入了新的单元格,但当核心数据中插入了许多对象时,它会导致崩溃,并给出以下错
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
- 使用
而不使用块操作。遵循Xcode提供的“获取结果”控制器模板。这可能比仅在主线程上保存要慢,因为UI将获得多个更新NSFetchedResultsControllerDelegate