0

コードの更新: Matthew の回答に続いて、コードをより正確に修正しようとしました。コードはセルを削除しますが、クラッシュしてエラーが発生します。

* キャッチされていない例外 'NSInvalidArgumentException' が原因でアプリを終了しています。理由: '* -[__NSPlaceholderArray initWithObjects:count:]: オブジェクト [0] から nil オブジェクトを挿入しようとしています'

checkboxTapped以下のコードは、私のコードで呼び出されたアクションからのものCustomCellです。アクションが起動されると、エラーが発生します。myindexPathが に等しいことがわかりましたNULL。これが問題である可能性が最も高いです。しかし、私はそれを修正する方法がわかりません。

[self.textLabel setTextColor:[UIColor grayColor]];
[self.detailTextLabel setTextColor:[UIColor grayColor]];

parent = [[ViewController alloc] init];

db = [[DataObject alloc] init];
NSIndexPath *indexPath = [[parent tableView] indexPathForSelectedRow];

[[parent array] removeObjectAtIndex:[indexPath row]];
[db deleteTaskAtIndex:[indexPath row]];

[[parent tableView] deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];

[db release];
[parent release];

Old:コードを調べて、使用していた配列を印刷しました。問題ないように見えますが、このエラーは引き続き発生します。

* キャッチされない例外 'NSRangeException' が原因でアプリを終了します。理由: '* -[__NSArrayM removeObjectAtIndex:]: 境界を超えたインデックス 1 [0 .. 0]'

私の推測では、それは私と関係があると思われましたが、私indexPathがどれだけ変更してもそれほど違いはありません.

-(void)checkboxTapped:(id)sender
{
    [sender setSelected:YES];

    [self.textLabel setTextColor:[UIColor grayColor]];
    [self.detailTextLabel setTextColor:[UIColor grayColor]];

    parent = [[ViewController alloc] init];
    UITableView *tableView = parent.tableView;
    NSMutableArray *array = [[NSMutableArray alloc] initWithArray:parent.array];
    [parent release];

    NSIndexPath *indexPath = [NSIndexPath indexPathForRow:[array count] inSection:1];

    [array removeObjectAtIndex:[indexPath row]];
    [db deleteTaskAtIndex:[indexPath row]];    
    [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationTop];

    [array release];

    [tableView endUpdates];
    [tableView reloadData];
}
4

1 に答える 1

1

あなたのコードでは、[indexPath 行] は [配列カウント] の値を返します。それはあなたが望むものではないでしょう。配列にオブジェクトが含まれていない場合は、インデックス 0 のオブジェクトを削除しようとしますが、オブジェクトが存在せず、エラーが発生します。配列に 1 つのオブジェクトがある場合、インデックス 1 のオブジェクトを削除しようとします。インデックス 1 にはオブジェクトがなく、インデックス 0 にはオブジェクトが 1 つしかないため、これも失敗します。

配列の最後のオブジェクトを削除したい場合は、count-1 のインデックスを使用する必要があります。配列が空であるかどうかを確認する必要がある場合もあります。

コメントのフォローアップに応じて更新

あなたは何もしたくありませんindexPathWithIndex最初のステップとして、次の行に沿ってコードを変更してみてください。

-(void)checkboxTapped:(id)sender
{
    [sender setSelected:YES];

    [self.textLabel setTextColor:[UIColor grayColor]];
    [self.detailTextLabel setTextColor:[UIColor grayColor]];

    parent = [[ViewController alloc] init];  // looks very odd - is an instance of this viewController active when the checkBox is tapped? If so, you don't want to create a new one, you want to access the existing one
    UITableView *tableView = parent.tableView;
    [parent release];  // this looks very dicey - when you release the parent, won't it release the tableView too?!

    int lastRow = [array count] - 1;
    if (lastRow == 0)
    {
         return; // bail if there are no rows in the table
    }

    NSMutableArray *array = [[NSMutableArray alloc] initWithArray:parent.array];
    [array removeObjectAtIndex: lastRow];  // not clear this will do anything as the reference to array is discarded later

    [db deleteTaskAtIndex: lastRow];   

    NSIndexPath *indexPath = [NSIndexPath indexPathForRow: lastRow inSection:1]; 
    [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationTop];

    [array release];

// [tableView endUpdates];  // there's no matching beginUpdates and you're only do one change operation anyway - leave this out

// [tableView reloadData]; // if you leave this line in, you won't see the delete animation - if you just want to delete one row, you wouldn't normally use reloadData, at least not if you want the animation
}

とはいえ、ここで他のことが起こっているようです。

で何が起こっていarrayますか? これを作成し、そこからアイテムを削除し、それへのポインターを破棄します。それがあなたが本当にやりたいことですか。より一般的なパターンは、他のオブジェクトから配列へのポインターを取得し、ここでその末尾にある項目を削除することです。

コードからは、テーブルのデータ ソースを更新する方法が明確ではありません。を使用deleteRowsAtIndexPaths:withRownAnimationするときは、テーブルのデータ ソースが最後にtableView:numberOfRowsInSection:. あなたのコードから、tableView dataSource がアイテムが 1 つ少ないことをどのように知るかは明らかではありませんdb

より基本的には、典型的な設計パターンでは、親ビューを解放すると tableView が解放されるため、'[parent release]' の後にそれが指すものは何でも未定義のことを行い、少なくとも一部のビューがクラッシュする可能性があります。時間。

于 2012-02-26T12:29:37.783 に答える