Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

iOS

deleting rows in iOS coredata app

I'm attempting to take puns one step further and delete rows. I get an error that has me baffled. Obviously it is not recounting the rows properly but I can't find out how to fix this as puns deals with sections rather differently to anything I can see via google.

The error is - Invalid update: invalid number of rows in section 0. The number of rows contained in an existing section after the update (0) 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, 2 deleted) and plus or minus the number of rows moved into or out of that section (0 moved in, 0 moved out).'

The delete code I am using is -

// Delete Rows

-(void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {

if (editingStyle == UITableViewCellEditingStyleDelete) {
    [self.tableView beginUpdates]; // Avoid NSInternalInconsistencyException

    // Delete the object that was swiped
   Pun *punToDelete = [self.fetchedResultsController objectAtIndexPath:indexPath];
    NSLog(@"Deleting (%@)", punToDelete.pun);
    [self.managedObjectContext deleteObject:punToDelete];
    [self.managedObjectContext save:nil];

    // Delete the (now empty) row on the table

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

           [self.tableView endUpdates];

     NSLog(@"%d", self.fetchedResultsController.sections.count);
}

}

Any advice would be awesome thanks

4 Answers

Bump :o)

Amit Bijlani
STAFF
Amit Bijlani
Treehouse Guest Teacher

No need to specifically call delete because that is already being called with methods of the NSFetchedResultsControllerDelegate like didChangeSection and didChangeObject.

So your code should really be:

-(void)tableView:(UITableView *)tableView 
  commitEditingStyle:(UITableViewCellEditingStyle)editingStyle 
  forRowAtIndexPath:(NSIndexPath *)indexPath {

  if  (editingStyle == UITableViewCellEditingStyleDelete) {

    // Delete the object 
    Pun *punToDelete = [self.fetchedResultsController objectAtIndexPath:indexPath];

    [self.managedObjectContext deleteObject:punToDelete];
    [self.managedObjectContext save:nil];

    }
}

Ideally you want to check for errors:

if (editingStyle == UITableViewCellEditingStyleDelete) {

    Pun *punToDelete = [self.fetchedResultsController objectAtIndexPath:indexPath];
    [self.managedObjectContext deleteObject:punToDelete];

           // Save the context.
    NSError *error;
    if (![self.managedObjectContext save:&error]) {
        /*
         Replace this implementation with code to handle the error appropriately.

         abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development. If it is not possible to recover from the error, display an alert panel that instructs the user to quit the application by pressing the Home button.
         */
        NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
        abort();
    }        
}

Excellent - I was almost close! Thanks Amit, as soon as I get home from work I will try it out.

Beautiful - works very nicely and I noticed it doesn't delete the row but the data so hopefully I can now change the format to loading an array of data with only the number/rating area editible (I changed the slider to a text view)