【问题标题】:Insertion and deletion of rows in UITableView sometimes causes the crash?UITableView中行的插入和删除有时会导致崩溃?
【发布时间】:2016-01-12 13:16:38
【问题描述】:

我在做非常平常的事情。 先修改数据模型,再更新TableView。但有时应用程序崩溃。 并抛出类似的错误(取决于插入或删除)。

Fatal Exception: NSInternalInconsistencyException
Invalid update: invalid number of rows in section 0. The number of rows contained in an existing section after the update (10) must be equal to the number of rows contained in that section before the update (10), plus or minus the number of rows inserted or deleted from that section (0 inserted, 1 deleted) and plus or minus the number of rows moved into or out of that section (0 moved in, 0 moved out).

这是我的插入代码。

[self.tableView beginUpdates];
[self.stories insertObject:story atIndex:0];
NSArray *indexPaths = @[[NSIndexPath indexPathForRow:0 inSection:0]];
[self.tableView insertRowsAtIndexPaths:indexPaths withRowAnimation:UITableViewRowAnimationFade];
[self.tableView endUpdates];

和删除代码。

[tableview beginUpdates];
[stories removeObject:story];
NSIndexPath *indexpath = [tableview indexPathForCell:cell];
if(indexpath) {
    [tableview deleteRowsAtIndexPaths:@[indexpath] withRowAnimation:UITableViewRowAnimationTop];
}
[tableview endUpdates];

【问题讨论】:

  • 看来[stores removeObject:story] 可能是罪魁祸首。检查以确保故事在所有情况下都在故事中,因为看起来有 10 个,而您尝试删除一个,但数据源仍然有 10 个对象。
  • [tableview reloadData] 在我看来很可疑...
  • @Both:我更喜欢 [stores removeObjectAtIndex:],并且 reloadData 在那个地方肯定是错误的 - 如果最后一行是,它将严重干扰 deleteRowsAtIndexPaths 并导致崩溃已删除。
  • 嘿伙计们更新了问题,这里@stefandouganhyde relaodData 从未在那里使用过。我不小心把它贴在这里了。
  • 调用–deleteRowsAtIndexPaths:withRowAnimation: 方法仅在条件的true 分支中;这里出现了不一致:您从模型中删除对象无条件,但您删除行仅有条件 - 可能会评估或可能不会评估,如果没有,你只是得到了崩溃。知道为什么需要调用[tableview indexPathForCell:cell] 方法真的很重要吗?因为您的委托方法中必须有正确的indexPath...

标签: ios objective-c uitableview uiviewanimation


【解决方案1】:

插入代码:

[self.stories insertObject:story atIndex:0];

[self.tableView beginUpdates];
NSArray *indexPaths = @[[NSIndexPath indexPathForRow:0 inSection:0]];
[self.tableView insertRowsAtIndexPaths:indexPaths withRowAnimation:UITableViewRowAnimationFade];
[self.tableView endUpdates];

删除代码:

[stories removeObject:story];

[tableview beginUpdates];
NSIndexPath *indexpath = [tableview indexPathForCell:cell];
[tableview deleteRowsAtIndexPaths:@[indexpath] withRowAnimation:UITableViewRowAnimationTop];
[tableview endUpdates];

注意:您不应该在更新 tableview 的行内向数组添加/删除对象。

【讨论】:

  • 对于单个插入/删除操作begin/endUpdates根本不需要。
  • @vadian,如果我错了,请纠正我,但来自Apple's doc "...If you do not make the insertion, deletion, and selection calls inside this block, table attributes such as row count might become invalid..." 对于这个问题,OP 正在做这两件事。因此,这可能是正确且必需的。
  • 关键词是calls(复数)指的是if you want subsequent ... calls
【解决方案2】:

[tableview reloadData];[self.tableView insertRowsAtIndexPaths:indexPaths withRowAnimation:UITableViewRowAnimationFade]; 中的任何一个

你也在[self.tableView beginUpdates];之间进行数据库操作 和[self.tableView endUpdates];。这不合适。

根据错误提示,表视图行和该表视图的数据源不匹配。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-10-22
    • 2013-01-09
    相关资源
    最近更新 更多