在索引路径问题处插入行

时间:2012-01-25 20:17:41

标签: ios cocoa-touch uitableview

我正在创建一个设置为数据层次结构的iOS应用。我在第一页上添加和删除对象甚至转换到下一页都没有问题。问题发生在第二页上,其设置与第一页完全相同。当我按下添加按钮添加对象时,程序崩溃并发回错误SIGABRT。

[self.tableView insertRowsAtIndexPaths:indexPaths withRowAnimation:YES]; << crashes on this line

这里是添加tapped的功能:

- (void)addTapped:(id)sender {
    StudentDoc *newDoc = [[[StudentDoc alloc] initWithTitle:@"New Student" rating:0 thumbImage:nil fullImage:nil] autorelease];
    [_students addObject:newDoc];

    NSIndexPath *indexPath = [NSIndexPath indexPathForRow:_students.count-1 inSection:0];
    NSArray *indexPaths = [NSArray arrayWithObject:indexPath];    
    [self.tableView insertRowsAtIndexPaths:indexPaths withRowAnimation:YES];

    [self.tableView selectRowAtIndexPath:indexPath animated:YES scrollPosition:UITableViewScrollPositionMiddle];
    [self tableView:self.tableView didSelectRowAtIndexPath:indexPath];
 }

部分中的行数:

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    return _students.count;
}

我一直认为计数是造成问题的原因,但我已经监控计数并保持一致。

总的来说,我不知道为什么它会崩溃,因为它之前的页面使用完全相同的功能在该页面上添加对象。有任何想法吗?

4 个答案:

答案 0 :(得分:2)

通常,如果你搞乱了你的数组或行索引,你会期望在控制台中记录异常,而不是SIGABRT。您是否在Xcode中启用了NSZombies和break-on-exceptions?这可能有助于诊断问题。

答案 1 :(得分:1)

您应该在开始更新和结束更新块之间的索引路径中插入插入行。

- (void)addTapped:(id)sender {

    StudentDoc *newDoc = [[[StudentDoc alloc] initWithTitle:@"New Student" rating:0 thumbImage:nil fullImage:nil] autorelease];
    [_students addObject:newDoc];

    NSIndexPath *indexPath = [NSIndexPath indexPathForRow:_students.count-1 inSection:0];
    NSArray *indexPaths = [NSArray arrayWithObject:indexPath];    

    [self.tableView beginUpdates];
    [self.tableView insertRowsAtIndexPaths:indexPaths withRowAnimation:YES];
    [self.tableView endUpdates];

    [self.tableView selectRowAtIndexPath:indexPath animated:YES scrollPosition:UITableViewScrollPositionMiddle];
    [self tableView:self.tableView didSelectRowAtIndexPath:indexPath];

 }

答案 2 :(得分:0)

我做的几乎一样,我把它分成两行:

NSInteger idx = [_students count] - 1;
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:idx inSection:0];

我想知道这是否会有所作为。

答案 3 :(得分:0)

您正在向数据源添加对象,但替换表中的现有行,而不是添加一行,从而导致indexPath中的一行但数据源中的两个项目阵列。

例如,如果_students中有一个项目,那么您将拥有一个索引路径{0,0}。添加行时,您将在indexPath {_students.count - 1,0}处添加它,该行将为{1 - 1,0}或{0,0}。您的数据源应该与您插入或删除的任何indexPath匹配,在您的情况下,您最终会在数据源中再添加一项而不是添加/删除。

如果您总是想要添加项目,而不是:

NSIndexPath *indexPath = [NSIndexPath indexPathForRow:_students.count-1 inSection:0];

你想:

NSIndexPath *indexPath = [NSIndexPath indexPathForRow:_students.count inSection:0];