Crash on reloadRowsAtIndexPath but not on reloadData

iphone, uitableview

Solution

I know that it has been a while since this question was asked but I think the problem might be that, reloadRowsAtIndexPaths relies on the prior existence of those rows in the table and internally deletes, recreates and inserts them back in (under the hood). So when you are calling the specific reload without those rows already being in the table, it is trying to delete a row that is not there.

I came across the same problem with a collection view. The reason why a full reload works is because it refreshes the whole thing and does not rely on prior state, only on the current condition of your data source.

This is my take on the problem.

Problem

I have a detailViewController and a MasterViewController. The MasterViewController is where I have the UITableView. I have two sections in my table, the top section for the list of items, the bottom section has one entry, @"Add new row". @"Add new row" goes to the detailViewController where a UITextField can be edited. Then when save is pressed, I do this: ``` - (IBAction)saveButtonPressed:(id)sender { if ([detailControllerDelegate respondsToSelector:@selector(setNewmap:)]) { if (self.textField.text.length > 0) { [self.textField endEditing:YES]; [detailControllerDelegate setValue:self.textField.text forKey:@"newmap"]; [self.navigationController popViewControllerAnimated:YES]; } } } ``` Then in the MasterViewController, ``` - (void)setNewmap:(NSString *)newmap { if (![newmap isEqualToString:_newmap]) { _newmap = newmap; [self.maps addObject:_newmap]; NSIndexPath *indexPath = [NSIndexPath indexPathForRow:[self.maps count] inSection:MAPS_SECTION]; [self.tableView reloadRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationAutomatic]; } } ``` It crashes on reloadRowsAtIndexPaths with the message: ``` Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'attempt to delete row 3 from section 0 which only contains 2 rows before the update' ``` I'm not sure why this gets called. I thought when you do tableViewUpdates, you update the model, which I do with `self.maps addObject:newmap];`. I logged the count and the count is correct. After updating the model, I thought you were free to reload the rows. If I don't reload the specific row, but just call reloadData on the tableView, then it does not crash. Not sure what the difference is here. It's like the numberOfRowsInSection delegate method does not get updated when I update the self.maps model.

Original source