2012-02-26 10 views
0

コードの更新: Matthewの答えに従って、より正確にコードを修正しようとしました。今のコードは、セルを削除しないだけでなく、クラッシュやエラーを与える:別のクラスを使用してセルを削除するとNSInvalidArgumentExceptionが発生する

* Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '* -[__NSPlaceholderArray initWithObjects:count:]: attempt to insert nil object from objects[0]'

次のコードは、私のCustomCellコードであるcheckboxTappedというアクションからです。アクションが発生すると、エラーが発生します。私はindexPathNULLと等しいことを知りました。それはおそらく問題です。しかし、私はそれを修正する方法を知らない。

[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]; 

旧:私は私のコードを見て、私は私が使っていた私の配列を印刷し、大丈夫に見える、まだこのエラーが解決しません。

* Terminating app due to uncaught exception 'NSRangeException', reason: '* -[__NSArrayM removeObjectAtIndex:]: index 1 beyond bounds [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]; 
} 

答えて

1

あなたのコードで[indexPath row]は[array count]の値を返します。それはあなたが望むものとは思えません。配列にオブジェクトがない場合は、インデックス0のオブジェクトを削除しようとしますが、オブジェクトは存在しないため、エラーが発生します。配列に1つのオブジェクトがある場合は、インデックス1のオブジェクトを削除しようとします。インデックス1のオブジェクトがないため、インデックス0のオブジェクトが1つだけ削除されます。

If配列内の最後のオブジェクトを削除する場合は、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:と尋ねられたときよりも1行少ないことを確認する必要があります。あなたのコードから、それを見つけるためにdbが指しているものが何であれ、それを見ているのでなければ、tableViewデータソースがどのようにアイテムが少ないかを知ることは明らかではありません。

もっと基本的には、典型的なデザインパターンでは、親ビューをリリースするときにtableViewがリリースされるため、 `[parent release] 'の後に指し示しているものはすべて未定義を行い、少なくともいくつかの時間。

+0

私は配列数を表示して '1'を表示しますので、' NSIndexPath * indexPath = [NSIndexPath indexPathWithIndex:array.count];で 'indexPath'宣言を切り替えました。今、私はこのエラーが発生します: '***キャッチされていない例外のためにアプリケーションを終了しています 'NSInternalInconsistencyException'、理由: 'UITableViewで使用するインデックスパスが無効です。表ビューに渡される索引パスには、セクションと行を指定する正確に2つの索引が含まれていなければなりません。可能であれば、UITableView.hのNSIndexPathのカテゴリを使用してください。 ' – Souljacker

+0

'db'はデータソース(plist)内のアイテムの追加、編集、削除などのすべてのデータソースアクションを組み立てた' NSObject'を指します。そして、[配列リリース]の '[親リリース]'を変更してもエラーは表示されませんでしたが、まだ削除されていません! – Souljacker

+0

更新されたコードを見てください。 – Souljacker

関連する問題