Pergunta

In my app I have NSFetchedResultsController which update my table in every change in the DB.

Sometime during change something went wrong in the app and the table remain empty no matter what I do (even if I change screen and return, the table remain empty).

Only after turn off the app and turn it back on everything seems to be fine again.

I isolate the problem to this error

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

It seems to be related to an un explain difference between the row number in "begin update" and "end update",which mean something when wrong when deleting or inserting rows.

This is kind of hard to debug using break point because in happens not very often.

Any suggestions?

my code :

#pragma mark - NSFetchedResultsControllerDelegate
- (void)controllerWillChangeContent:(NSFetchedResultsController *)controller
{   
     [self.guiTableView beginUpdates];  
}

- (void)controller:(NSFetchedResultsController *)controller didChangeSection:(id <NSFetchedResultsSectionInfo>)sectionInfo
           atIndex:(NSUInteger)sectionIndex forChangeType:(NSFetchedResultsChangeType)type
{   
        switch(type) {
            case NSFetchedResultsChangeInsert:

                [self.guiTableView beginUpdates];

                [self.guiTableView insertSections:[NSIndexSet indexSetWithIndex:sectionIndex] withRowAnimation:UITableViewRowAnimationAutomatic];

                 [self.guiTableView endUpdates];
                break;

            case NSFetchedResultsChangeDelete:
                [self.guiTableView beginUpdates];

                [self.guiTableView deleteSections:[NSIndexSet indexSetWithIndex:sectionIndex] withRowAnimation:UITableViewRowAnimationLeft];


                [self.guiTableView endUpdates];

    //            if (controller.sections.count==0) {
    //                [self alertAboutNothingInMyAssetsAndPop];
    //            }
                break;
        }

}

- (void)controller:(NSFetchedResultsController *)controller didChangeObject:(id)anObject
       atIndexPath:(NSIndexPath *)indexPath forChangeType:(NSFetchedResultsChangeType)type
      newIndexPath:(NSIndexPath *)newIndexPath
{   
    UITableView *tableView = self.guiTableView;

    SOOptionCell *cell;

    switch(type) {
        case NSFetchedResultsChangeInsert:

            [tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationAutomatic];

            break;

        case NSFetchedResultsChangeDelete:

            [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationLeft];


            break;

        case NSFetchedResultsChangeUpdate:
            cell = (SOOptionCell *)[tableView cellForRowAtIndexPath:indexPath];
            [self configureCell:cell atIndexPath:indexPath animated:YES];
            break;

        case NSFetchedResultsChangeMove:

            [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
            [tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath]withRowAnimation:UITableViewRowAnimationAutomatic];


            break;
    }   
}   

- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller{       

     [self.guiTableView endUpdates];    
}
Foi útil?

Solução

First, remove all of your -beginUpdates and -endUpdates calls inside of the delegate methods. There should only be one of each. One -beginUpdates in the -controllerWillChangeContent: and one -endUpdates in the -controllerDidChangeContent:. I would go so far as to say that you should change the other methods back to the examples provided by Apple instead of writing them yourself.

Once you do that does the discrepancy go away? I suspect it will.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top