UITableViewで行を削除しようとして躓いたメモ

UITableView の編集モードを使って

// UITableView に表示するデータの件数を返す
-(NSInteger)tableView:(UITableView*)tableView numberOfRowsInSection:(NSInteger)section
{
    return [self.model dataCount];
}

// 行はすべて編集可能にする
-(BOOL)tableView:(UITableView*)tableView canEditRowAtIndexPath:(NSIndexPath*)indexPath
{
    return YES;
}

// UITableView が編集モードのときの処理
-(void)tableView:(UITableView*)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath*)indexPath
{
    if (editingStyle == UITableViewCellEditingStyleDelete)
    {
        // データを削除
        [self.model deleteData:indexPath.row];

        // UITableView からも削除
        [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath]
                         withRowAnimation:UITableViewRowAnimationAutomatic];
    }
}

// UITableView のモードを切り替える
-(IBAction)toggleEditingMode:(id)sender
{
    if (self.tableView.editing)
    {
        [self.tableView setEditing:NO animated:YES];
    }
    else
    {
        [self.tableView setEditing:YES animated:YES];
    }
}

という感じで行の削除処理を実装してみたけど、いざ編集モードに切り替えて削除を実行してみると deleteRowsAtIndexPaths のところで

2012-10-11 20:24:24.163 AppName[4137:c07] *** Assertion failure in -[UITableView _endCellAnimationsWithContext:], /SourceCache/UIKit_Sim/UIKit-2372/UITableView.m:1070
2012-10-11 20:24:36.079 AppName[4137:c07] CRASH: Invalid update: invalid number of rows in section 0.  The number of rows contained in an existing section after the update (2) must be equal to the number of rows contained in that section before the update (2), 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).

っていうエラーが発生してしまった。

試しに

[tableView beginUpdates];
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath]
                 withRowAnimation:UITableViewRowAnimationAutomatic];
[tableView endUpdates];

にしてみたけど、やっぱりダメ。

なんでだろなー、おかしーなーって思ってたら、データの永続化には CoreData を使っていて、deleteObject で削除したけど ManageObjectContext を保存していなかったorz

削除したつもりで、実際は削除されておらず、データ件数を取得するメソッドは削除前の件数を返してしまっていた、というわけか。

CoreData で編集・削除したときは忘れずに保存しておかないとな。あと、UITableView から行を削除したら、tableView:numberOfRowsInSection が返す件数も減らしておかないといけないみたいだ。