简体   繁体   English

Objective-C-iOS UITableView底部行在删除时崩溃

[英]Objective-C - iOS UITableView bottom row crash on delete

I am extending the learn iOS programming today tutorial to include delete functionality. 我正在扩展“立即学习iOS编程”教程,以包括删除功能。

I have modified the tableView didSelectRowAtIndexPath: method thusly: 我因此修改了tableView didSelectRowAtIndexPath:方法:

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {

    [tableView deselectRowAtIndexPath:indexPath animated:NO];
    ToDoItem *tappedItem = [self.toDoItems objectAtIndex:indexPath.row];
    if (tappedItem.completed) {

        [tableView beginUpdates];
        [self.toDoItems removeObjectAtIndex:indexPath.row];

        [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationBottom];
        [tableView endUpdates];

    } else {
        tappedItem.completed = YES;
    }
    [tableView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationNone];
}

In a section with three rows, it works as expected. 在具有三行的节中,它可以按预期工作。 Tapping produces a checkmark, tapping a check marked item deletes it. 点击会产生一个选中标记,点击选中标记的项目将其删除。 But if I tap the bottom row, it crashes with 'attempt to delete row 2 from section 0 which only contains 2 rows before the update' . 但是,如果我点击最下面的行,则会崩溃,并导致'attempt to delete row 2 from section 0 which only contains 2 rows before the update' Note this is happening when the other two rows are still there (my searches found numerous posts where there was a crash when someone was deleting the last remaining row--not the case here). 请注意,这是在其他两行仍然存在时发生的(我的搜索发现许多帖子,其中有人删除最后剩余的行时发生了崩溃-此处不是这种情况)。 The bottom row will mark itself completed just fine. 最下面一行将标记为已完成。

Also note, moving the array changing call out of the beginUpdates block changes the error from row 2 to row 3 ... contains 3 rows. 还要注意,将数组更改调用移出beginUpdates块会将错误从第2 row 3 ... contains 3 rows.更改为row 3 ... contains 3 rows.

TIA for any assistance. TIA寻求任何帮助。

Edit: 编辑:

I have fixed the problem by moving [tableView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationNone]; 我通过移动[tableView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationNone];解决了此问题[tableView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationNone]; inside of the else block. else块的内部。 Can someone explain why? 有人可以解释为什么吗?

If you use deleteRowsAtIndexPaths , there is no point in trying to reload the row that you deleted. 如果使用deleteRowsAtIndexPaths ,则尝试重新加载已删除的行没有任何意义。 And, obviously, if you try to reload a cell for an indexPath that is no longer valid, then you will have the sort of problem you describe. 而且,很显然,如果您尝试为不再有效的indexPath重新加载单元格,那么您将遇到所描述的问题。

Let's say you have 10 rows, you don't want to say, effectively, "delete the tenth row; now reload the tenth row in a table that now only has nine rows." 假设您有10行,而您实际上并不想说“删除第十行;现在将第十行重新加载到现在只有九行的表中”。 You can easily imagine why that is problematic. 您可以轻松想象为什么这是有问题的。

In this case, you should remove the call to reloadRowsAtIndexPaths altogether. 在这种情况下,您应该完全删除对reloadRowsAtIndexPaths的调用。 You only have to call reload... if the contents of some of the remaining cells change. 如果某些剩余单元格的内容发生变化,则只需调用reload... If you're just inserting or deleting rows, then just do that, and no call to reloadRowsAtIndexPaths is needed. 如果您只是插入或删除行,则只需执行此操作,无需调用reloadRowsAtIndexPaths

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM