CoreData error driving me crazy… CoreData: Serious application error. An exception caught from delegate of NSFetchedResultsController

做~自己de王妃 提交于 2019-11-30 00:38:14

The UITableView sanity checking works like this:

At the line [self.tableView beginUpdates]; the tableView calls your tableView:numberOfRowsInSection: delegate method, which appears to be returning 3. At the line [self.tableView endUpdates]; it calls it again and it seems to be returning 4. Therefore, the tableView is expecting you to insert 1 row between these two lines. In fact, no rows are being inserted so the tableView fails an assertion. (You can see the expected and actual row counts in the assertion message).

The increase from 3 rows to 4 rows shows that your NSFetchedResultsController is noticing the newly inserted Core Data item correctly. What you need to do is put a breakpoint at the start of your controller:didChangeObject:atIndexPath:forChangeType: method and step through it when you switch to the 2nd tab after inserting an item. You should see the NSFetchedResultsChangeInsert: case of the switch statement being performed but this is obviously not happening.

Hopefully, you can figure out why the insertion is not taking place - otherwise come back and let us know what you actually saw when stepping through this method.

EDITED TO ADD:

OK, so your NSFetchedResultsController delegate methods in the 2nd view controller are called when you switch to that tab rather than immediately when the new item is inserted on tab 1. This means that the 2nd view controller is not seeing the insert (which should happen immediately) and is actually responding to some other Core Data update notification later that occurs when you switch to tab 2. The fetched results controller is working with stale information at the beginUpdates line (there are actually 4 items in the result set here not 3). By the time it gets to the endUpdates line it has refreshed its fetch and found an unexpected insert.

The NSFetchedResultsController delegate methods are really designed to update UI in-place while you are making changes AND the controller's view is visible. In your case, you are making changes and THEN displaying the new view controller. The pattern that you really should be using is to refresh the tableview in your viewWillAppear method of controller 2. Something like this should do it:

- (void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];

    NSError *error = nil;
    [resultsController performFetch:&error]; // Refetch data
    if (error != nil) {
        // handle error
    }

    [self.tableView reloadData];
}

This will make sure that whenever you switch to tab 2 it is working with fresh data from the model.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!