0

代码更新:在马修的回答之后,我尝试更正我的代码以使其更正确。现在代码确实删除了单元格,但也会崩溃并给出错误:

* 由于未捕获的异常“NSInvalidArgumentException”而终止应用程序,原因:“* -[__NSPlaceholderArray initWithObjects:count:]: 尝试从 objects[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];

旧:我查看了我的代码并打印了我正在使用的数组,它看起来很好,但这个错误仍然存​​在。

* 由于未捕获的异常“NSRangeException”而终止应用程序,原因:“* -[__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];
}
4

1 回答 1

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 将被释放,所以在 `[parent release]' 之后它指向的任何东西都会做一些未定义的事情,并且可能至少会崩溃一些时间。

于 2012-02-26T12:29:37.783 回答