NSFetchedResultsController: delete 1 row crashes the app

柔情痞子 提交于 2019-11-28 09:52:01

问题


Deleting a row from a UITableView fed by an NSFetchedResultsController causes my app to crash.

Error is:

* Assertion failure in -[UITableView _endCellAnimationsWithContext:], /SourceCache/UIKit/UIKit-2903.23/UITableView.m:1330
*
Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Invalid update: invalid number of rows in section 0. The number of rows contained in an existing section after the update (1) must be equal to the number of rows contained in that section before the update (1), plus or minus the number of rows inserted or deleted from that section (0 inserted, 1 deleted) and plus or minus the number of rows moved into or out of that section (0 moved in, 0 moved out).'

I want only swipe-to-delete. My deletion code goes like this:

- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{  
    [self.tableView beginUpdates];  
    SequenceData *sd = [self.fetchedResultsController objectAtIndexPath:indexPath];  
    [self.managedObjectContext deleteObject:sd];  
    [self.tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath]
                          withRowAnimation:UITableViewRowAnimationFade];  
    [self.tableView endUpdates];  
}

My NSFetchedResultsController is set up just like in Ray Wanderlich's tutorial (http://www.raywenderlich.com/999/core-data-tutorial-for-ios-how-to-use-nsfetchedresultscontroller)

Number of rows is determined by:

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {    
    id sectionObjects = [[self.fetchedResultsController sections] objectAtIndex:section];  
    NSInteger nbObjects = [sectionObjects numberOfObjects];  
    return nbObjects;  
}

It looks like the fetch is not updating (number of rows does not vary). Do I need to fetch myself (isn't this taking care of by the fetch controller)?

There is obviously something basic I am missing here. Don't hesitate to suggest basic answers.

I first implemented this with the controller: didChangeObject: ... method. Error was the same, but some details differed.

Edit I believe my problem is fixed. Both answers (From CX and Martin) helped me find it. Martin got the answer because of the explanations that helped me understand a little bit better...


回答1:


Don't call

[self.tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];

if you use a fetched results controller. Only delete the object with

[self.managedObjectContext deleteObject:sd];

The fetched results controller delegate method didChangeObject: is then called automatically, and that calls deleteRowsAtIndexPaths:.

So in your case, the row was deleted twice, and that caused the exception.

Note that you don't need beginUpdates/endUpdates here.




回答2:


If you want to delete a row you need to delete managedObject only.

if (editingStyle == UITableViewCellEditingStyleDelete)
{
    [self.managedObjectContext deleteObject:[self.fetchedResultsController objectAtIndexPath:indexPath]];

    NSError *error = nil;
    if (![self.managedObjectContext save:&error]) {
        // handle error
    }
}

Deleting the managed object triggers the NSFetchResultController delegate methods, and they will update the tableView.

Edit

You should implement NSFetchResultController delegate method

- (void)controller:(NSFetchedResultsController *)controller didChangeObject:(id)anObject atIndexPath:(NSIndexPath *)indexPath forChangeType:(NSFetchedResultsChangeType)type newIndexPath:(NSIndexPath *)newIndexPath{
switch(type) {
 case NSFetchedResultsChangeDelete:
            [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
            break;
}


////
   default:
   break;
    }

Because when you work with data source like NSFetchedResultsController, all changes must come from there and your table only reflects them.



来源:https://stackoverflow.com/questions/21222840/nsfetchedresultscontroller-delete-1-row-crashes-the-app

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