ここに記載している内容は、私が出くわした時の解決法且つ手っ取り早いやり方です。抜本的な対策ではないのでご注意ください
UITableViewの
- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)sourceIndexPath toIndexPath:(NSIndexPath *)destinationIndexPath
の中でCoreDataのUpdateを行ったら以下のようなエラーが出て、すっぽりドツボにハマりました
CoreData: error: Serious application error. Exception was caught during Core Data change processing.
This is usually a bug within an observer of NSManagedObjectContextObjectsDidChangeNotification.
Invalid update: invalid number of rows in section 0.
The number of rows contained in an existing section after the update (5) must be equal to the number of rows contained in that section before the update (5),
plus or minus the number of rows inserted or deleted from that section (0 inserted, 1 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)
*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Invalid update: invalid number of rows in section 0. The number of rows contained in an existing section after the update (5) must be equal to the number of rows contained in that section before the update (5), plus or minus the number of rows inserted or deleted from that section (0 inserted, 1 deleted) and plus or minus the number of rows moved into or out of that section (0 moved in, 0 moved out).'
色々書いてありますが、簡単に言うと、更新後のUITableViewのメソッドが、CoreDataのfetchedResultsControllerを呼ぶのですが、
それを読み込んだ時点で、ManagedObjectContextと不整合が起きた為、この手のエラーが発生しました。
なので、私が出くわした際は、以下のメソッドの中身を変更しました。
- (void)controller:(NSFetchedResultsController *)controller didChangeObject:(id)anObject
atIndexPath:(NSIndexPath *)indexPath forChangeType:(NSFetchedResultsChangeType)type
newIndexPath:(NSIndexPath *)newIndexPath
{
case NSFetchedResultsChangeDelete:
/*処理*/
break;
case NSFetchedResultsChangeMove:
[self.tableView reloadData];
break;
}
今作っているアプリは、リアルタイムにCellの更新を行わなくても良いものなので、ここでのcell更新を解除し、endUpdate内でreloadDataを行うようにしました。
- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller {
@try {
[self.tableView endUpdates];
}
@catch (NSException *exception) {
/*error!*/
}
@finally {
}
}
リアルタイムverも、取り掛かって見ようと思ったのですが、時間切れなのでここまでで。