如何检查UICollectionView中插入和删除的项目,看到意外的删除项目

我在这个特定的情况下努力集成UICollectionViewUICollectionView

在我的视图控制器中,我获取父实体,但在集合视图中显示其多个子实体。 在这个视图控制器(使用insertNewObjectForEntityForName )中创build一个新的Parent实体并自动创build一个Child实体并将其添加到具有addChildObject的父实体时,我可以通过按下一个button来添加更多的Child实体,并成功保存该对象。 不幸的是,由于某种原因, NSFetchedResultsControllerDelegate方法不被调用,具体来说, controllerDidChangeContent从不被调用,集合视图不会被更新。

当我获取一个已经存在的Parent实体,然后尝试通过添加新的Child对象来更改它时,该应用程序崩溃,出现以下exception:

 *** Assertion failure in -[UICollectionView _endItemAnimationsWithInvalidationContext:tentativelyForReordering:], /BuildRoot/Library/Caches/com.apple.xbs/Sources/UIKit/UIKit-3505.17/UICollectionView.m:4211 

最后给出这个错误:

 CoreData: error: Serious application error. An exception was caught from the delegate of NSFetchedResultsController during a call to controllerDidChangeContent:. Invalid update: invalid number of items in section 0. The number of items contained in an existing section after the update (5) must be equal to the number of items contained in that section before the update (4), plus or minus the number of items inserted or deleted from that section (1 inserted, 1 deleted) and plus or minus the number of items moved into or out of that section (0 moved in, 0 moved out). with userInfo (null) 

最让我感到困惑的是,它表明在(1 inserted, 1 deleted)中存在一个已删除的项目,实际上,我只是添加一个项目(用insertNewObjectForEntityForName初始化一个Child实体并将其与[parent addChildObject:child]

在所有这些情况下,我没有保存上下文。 我期望添加对象到父实体触发NSFetchedResultsControllerDelegate方法。

FetchResultsController设置代码:

 - (NSFetchedResultsController *) fetchedResultsController { if (_fetchedResultsController != nil) { return _fetchedResultsController; } NSFetchRequest *fetchRequest = [self emojiFetchRequest]; _fetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:[self managedObjectContext] sectionNameKeyPath:nil cacheName:nil]; _fetchedResultsController.delegate = self; return _fetchedResultsController; } 

viewWillAppear初始化父对象:

 [[self fetchedResultsController] performFetch:&error]; id fetchedObject = [[[self fetchedResultsController] fetchedObjects] firstObject]; if (fetchedObject != nil) { self.parent = (Parent *)fetchedObject; self.navigationItem.title = self.parent.name; } else { self.navigationItem.title = @"New parent"; self.parent = [NSEntityDescription insertNewObjectForEntityForName:@"Parent" inManagedObjectContext:[self managedObjectContext]]; Child *child = [NSEntityDescription insertNewObjectForEntityForName:@"Child" inManagedObjectContext:[self managedObjectContext]]; [self.parent addFramesObject:frame]; } 

添加新的子对象:

 Child *child = [NSEntityDescription insertNewObjectForEntityForName:@"Child" inManagedObjectContext:[self managedObjectContext]]; [self.parent addChildrenObject:child]; [self.collectionView reloadData]; // if this isn't done, the crash happens // but this can't animate changes 

核心数据模型:

核心数据模型

有没有办法看到这些对象? 我试过loggingdidChangeObject ,我只看到一个插入。 我不删除任何东西。 如果有人有任何其他的想法,我会很高兴听到他们。

编辑

如果我添加对象后调用[self.collectionView reloadData] ,一切似乎正常工作,而不会崩溃。 但是,如果这些更改是dynamic的,这不能用reloadData完成,而且我感觉到我正在做的事情有些根本性的错误,我想解决它。

最好的解决scheme:在获取的结果控制器中获取Child实体,按parent过滤。

对于插入,请使用NSFetchedResultsControllerDelegate的普通香草实现。 这将提供一个不错的animation或让你自己添加。