I seem to be encountering a very odd problem which only occurs when trying to insert a new NSManagedObject into a new section. Basically my sections are days and individual cells are associated with times. When I MOVE an object to a day which doesn't currently have another object (table row) associated with the day, the table needs to create a new section and move the row. Instead of this happening properly I'm getting the following:
Serious application error. An exception was caught from the delegate of NSFetchedResultsController during a call to -controllerDidChangeContent:. * -[NSMutableArray removeObjectAtIndex:]: index 1 beyond bounds [0 .. 0] with userInfo (null)
Inserting a new object for a day that currently has no other objects seems to work fine.
The problem seems to be somewhere in this code, but I can't seem to figure out what's wrong with it. controller:didChangeSection:...
seems to get called first with an insert and a delete then controller:didChangeObject:...
is called with NSFetchedResultsChangeMove. So the order is:
NSFetchedResultsChangeInsert (in didChangeSection) NSFetchedResultsChangeDelete (in didChangeSection) NSFetchedResultsChangeMove (in didChangeObject)
/**
Delegate methods of NSFetchedResultsController to respond to additions, removals and so on.
*/
- (void)controllerWillChangeContent:(NSFetchedResultsController *)controller {
// The fetch controller is about to start sending change notifications, so prepare the table view for updates.
[self.plainTableView beginUpdates];
}
- (void)controller:(NSFetchedResultsController *)controller
didChangeObject:(id)anObject
atIndexPath:(NSIndexPath *)indexPath
forChangeType:(NSFetchedResultsChangeType)type
newIndexPath:(NSIndexPath *)newIndexPath {
UITableView *tv = self.plainTableView;
switch(type) {
case NSFetchedResultsChangeInsert:
[tv insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationFade];
break;
case NSFetchedResultsChangeDelete:
[tv deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
break;
case NSFetchedResultsChangeUpdate:
[self configureCell:(UITableViewCell *)[tv cellForRowAtIndexPath:indexPath] atIndexPath:indexPath];
break;
case NSFetchedResultsChangeMove:
[tv deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
// Reloading the section inserts a new row and ensures that titles are updated appropriately.
[tv reloadSections:[NSIndexSet indexSetWithIndex:newIndexPath.section] withRowAnimation:UITableViewRowAnimationFade];
break;
}
}
- (void)controller:(NSFetchedResultsController *)controller
didChangeSection:(id <NSFetchedResultsSectionInfo>)sectionInfo
atIndex:(NSUInteger)sectionIndex
forChangeType:(NSFetchedResultsChangeType)type {
switch(type) {
case NSFetchedResultsChangeInsert:
[self.plainTableView insertSections:[NSIndexSet indexSetWithIndex:sectionIndex] withRowAnimation:UITableViewRowAnimationFade];
break;
case NSFetchedResultsChangeDelete:
[self.plainTableView deleteSections:[NSIndexSet indexSetWithIndex:sectionIndex] withRowAnimation:UITableViewRowAnimationFade];
break;
}
}
- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller {
// The fetch controller has sent all current change notifications, so tell the table view to process all updates.
[self.plainTableView endUpdates];
}
I thought this was all just standard template code though. Does anyone have any idea what might be wrong?
Actually it also happens when trying to insert a new row into a day which already exists, but not when inserting a new row/object for a day that doesn't already exist.