代码更新:关于Matthew的回答我尝试更正我的代码更正确。现在代码确实删除了单元格,但也崩溃了,并给出了一个错误:
*由于未捕获的异常'NSInvalidArgumentException'而终止应用程序,原因:'* - [__ NSPlaceholderArray initWithObjects:count:]:尝试从对象[0]中插入nil对象
以下代码来自名为checkboxTapped
的操作,该操作位于我的CustomCell
代码中。一旦触发动作,它就会出错。我发现我的indexPath
等于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];
旧:我查看了我的代码并打印了我正在使用的数组,看起来很好,但这个错误仍然存在。
*由于未捕获的异常'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];
}
答案 0 :(得分:1)
在你的代码中[indexPath row]将返回[array count]的值。这不太可能是你想要的。如果你的数组中有零个对象,你将尝试删除索引0处的对象。但是没有对象,你会收到错误。如果你的数组中有1个对象,你将尝试删除索引1处的对象。再次,这将失败,因为索引1处没有对象,只有索引0处的一个对象。
如果要删除数组中的最后一个对象,则需要使用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将如何知道只有少一个项目,除非它正在查看db
指向的任何内容以便找到它。
更基本的是,对于典型的设计模式,当您释放父视图时,tableView将被释放,所以无论它在“父发布”之后指向什么,都会做一些未定义的事情并且可能至少崩溃有时候。