在索引处重新加载时会在tableview上崩溃

时间:2017-01-24 04:20:32

标签: ios swift uitableview

override func viewDidLoad() {

    _previewView = previewView
    super.viewDidLoad()
    delegate = self
    tableView.dataSource = self
    tableView.delegate = self

    let currentUser = (FIRAuth.auth()?.currentUser?.uid)!
    let currentUserRef =  DataService.ds.REF_USERS.child(currentUser)
    let cutoff = Double((Date().timeIntervalSince1970) - 60 * 4 *  200000000)

    currentUserRef.child("invitedToPosts").queryOrdered(byChild: "timestamp").queryStarting(atValue: cutoff).observe(.childAdded) { (snapshot: FIRDataSnapshot) in
        let post = snapshot.key
        self.posts.insert(post, at: 0)
        let indexPath = IndexPath(item: 0, section: 0)
        self.tableView.reloadRows(at: [indexPath], with: .fade)
    }

}

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return posts.count
}

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = UITableViewCell()
    let post = posts[indexPath.row]
    cell.textLabel?.text = post
    return cell
}

这样做的目的是获取帖子,获取帖子的密钥,在postsArray的前面添加该密钥,然后仅重新加载该单元格。

当我运行应用程序时,我收到错误:

*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'attempt to delete row 0 from section 0 which only contains 0 rows before the update'

当我运行tableview.reloadData()时,代码工作正常,但这会崩溃。

为什么会发生这种情况/如何让它发挥作用?

3 个答案:

答案 0 :(得分:2)

只有在您真正希望重新加载现有行时才能使用reloadRows(at:)

在您发布的代码中,情况并非如此。在您的代码中,您要向数据模型添加新行。因此,您需要在表视图中插入一个新行,而不是重新加载现有行。

替换行:

self.tableView.reloadRows(at: [indexPath], with: .fade)

使用:

self.tableView.insertRows(at: [indexPath], with: .fade)

使用reloadData有效,因为它只是完全重新加载表视图。您对数据模型所做的更改并不重要。

答案 1 :(得分:1)

当像您一样重新编码特定行时,请确保tableView中有这样一行。

此处出现错误是因为您尝试删除tableView中不存在的行(代码不存在问题)。

如果你打电话给reloadData(),它将再次执行所有代表。

答案 2 :(得分:0)

正如RMaddy所说,使用insertRows可行。但是如果你甚至可以删除一些行,则需要使用reloadRows。

因此,在这种情况下,您可以做的是检查indexPath是否存在,然后相应地重新加载/插入。