开发者

fetchedResultsContext does not really delete object and causes assertion issue in commitEditingStyle

I am having a weird issue and need some help.

I am on a core data project and did not yet use a fetchedResultsController, just working with fetchRequets and arrays to populate zableviews. So now I decided to change and make use of FRC ...

Everything was pretty easy 开发者_StackOverflow中文版so far ... but with commitEditingStyle I am having issues since then - when deleting rows I am thrown an exception like this one:

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.

In the end I found out that it is because the object I want to delete remains in FRC ... I put some NSLog sections in liko so:

    NSLog(@"Number before deleting: %i - deleting %@",[[fetchedResultsController fetchedObjects] count], [fetchedResultsController objectAtIndexPath:indexPath]);

    NSManagedObjectContext *context = [fetchedResultsController managedObjectContext];
    [context deleteObject:[fetchedResultsController objectAtIndexPath:indexPath]];

    NSLog(@"Number before saving: %i",[[fetchedResultsController fetchedObjects] count]);

    NSError *error;
    if (![context save:&error]) {

        [NSException raise:NSGenericException format:@"Following error occured when trying to delete %@: %@", [fetchedResultsController objectAtIndexPath:indexPath], [error description]];
    }

    NSLog(@"Number after saving: %i",[[fetchedResultsController fetchedObjects] count]);

    NSArray * cellsToDelete = [NSArray arrayWithObject:indexPath];
    [tableView deleteRowsAtIndexPaths:cellsToDelete withRowAnimation:UITableViewRowAnimationFade];

The result was this:

2011-05-20 14:49:35.398 Nivellator[6000:207] Number before deleting: 3
2011-05-20 14:49:35.399 Nivellator[6000:207] Number before saving: 3
2011-05-20 14:49:35.404 Nivellator[6000:207] Number after saving: 3

Of course it will puke when I'm telling the tableview that it'll get 3 rows but only pass two ... but what's wrong here?

My old code was looking like this and worked without any issues ...

-(void) tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
    if ([tableView isEqual:self.entityTableView] == YES) {
        if (editingStyle != UITableViewCellEditingStyleDelete) {
            return;
        }

        if ([self.entityArray count] <= indexPath.row) {
            return;
        }

        Member *thisEntity = [self.entityArray objectAtIndex:indexPath.row];
        [delegate.managedObjectContext deleteObject:thisEntity];

        NSError *savingError = nil;

        if ([delegate.managedObjectContext save:&savingError] == YES) {

            // Remove the entity from the Array and delete the corresponding table cell with animation
            //
            [self.entityArray removeObject:thisEntity];

            NSArray * cellsToDelete = [NSArray arrayWithObject:indexPath];
            [tableView deleteRowsAtIndexPaths:cellsToDelete withRowAnimation:UITableViewRowAnimationFade];
        } else {
            /* Error handling missing */
        }
    }
}

OK

in the end it came down to RTFM ... so I made it partly work by changing the code such as:

-(void) tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
    if ([tableView isEqual:self.entityTableView] == YES) {
        if (editingStyle != UITableViewCellEditingStyleDelete) {
            return;
        }

        NSManagedObjectContext *context = [fetchedResultsController managedObjectContext];
        [context deleteObject:[fetchedResultsController objectAtIndexPath:indexPath]];

        NSError *error;
        if (![context save:&error]) {

            [NSException raise:NSGenericException format:@"Following error occured when trying to delete %@: %@", [fetchedResultsController objectAtIndexPath:indexPath], [error description]];
        }

        if ([fetchedResultsController performFetch:&error]) {

            [tableView beginUpdates];

            NSArray * cellsToDelete = [NSArray arrayWithObject:indexPath];
            [tableView deleteRowsAtIndexPaths:cellsToDelete withRowAnimation:UITableViewRowAnimationFade];

            [tableView endUpdates];
        } else {

            [NSException raise:NSGenericException format:@"Following error occured when trying to delete %@: %@", [fetchedResultsController objectAtIndexPath:indexPath], [error description]];
        }
    }
}

But when I'm using sectments in my FRC I still get the same error ... I cannot find anything more than this to do with the FRC ...

Any idea?


  1. Delete the FRC's cache after the delete
  2. Check that you have implemented the FRC's delegate methods properly.
  3. Make sure you freeze the tableview with beginUpdates before you run the FRC's delegate methods.
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜