在`reloadRowsAtIndexPath`崩溃

时间:2015-06-30 07:23:24

标签: ios swift uitableview objective-c-blocks

我有一个分页tableView,每次用户滚动时都会加载一个新页面,有点像Instagram Feed。在获取新页面后,tableView的重新加载发生在回调中。代码看起来像这样:

func fetchNewPage() {
    ws.fetchNewPage(completion: { () -> Void in {
        updateDataSource()
        self.tableView.reloadData()
    })
}

同时,tableView中的单元格应在用户点击它们时更新(它们会更改背景颜色)。这是在调用WS之后发生的。代码看起来像这样:

func markAsSeen(indexPath: NSIndexPath) {
     ws.markAsSeen(completion: { () -> Void in {
         self.tableView.reloadRowsAtIndexPaths([indexPath], withRowAnimation: .None)
     })
}

我的问题是dataSource可以在markAsSeen完成块执行时更改元素的数量。然后应用程序崩溃了这个例外:

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

所以,我的问题是你是否知道如何同步这两个块,以便应用程序不再崩溃,但行也会更新。

非常感谢

1 个答案:

答案 0 :(得分:0)

您对同步的想法是正确的。作为选项,您可以在主队列上执行数据源的更新。在这种情况下,数据源和UI更新将排队并连续执行,因为数据的更改将是可预测和一致的。

另外值得一提的是,所有UI调用都必须在主线程上执行。从你的代码中可以清楚地知道它是真的。