LoginSignup
2
2

More than 5 years have passed since last update.

CoreDataでSerious application error

Posted at

ここに記載している内容は、私が出くわした時の解決法且つ手っ取り早いやり方です。抜本的な対策ではないのでご注意ください

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も、取り掛かって見ようと思ったのですが、時間切れなのでここまでで。

2
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2