user6820041
user6820041

Reputation: 1213

Crash on tableview when reloading at index

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
}

The goal of this is to grab a post, get the key of the post, add that key at the front of a postsArray and then reload only that cell.

When I run the app I get the error:

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

Code works fine when I just run tableview.reloadData(), but this crashes out.

Any ideas why this is happening/ how to get this to work?

Upvotes: 2

Views: 1858

Answers (3)

Clinton D'Souza
Clinton D'Souza

Reputation: 301

as RMaddy said, using insertRows works. But if you may even remove some rows, you will need to use reloadRows.

So in that case, what you can do is do a small check if that indexPath exists and then reload/insert accordingly.

Upvotes: 0

rmaddy
rmaddy

Reputation: 318774

The use of reloadRows(at:) should only be used when you actually wish to reload existing rows.

In the code you posted, this is not the case. In your code, you are adding a new row to your data model. So you need to insert a new row into the table view, not reload an existing row.

Replace the line:

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

with:

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

Using reloadData works because it simply does a complete reload of the table view. It doesn't matter what changes you've made to the data model.

Upvotes: 3

Saranjith
Saranjith

Reputation: 11557

When you relaoding a specific row like you did, Be sure you have such a row in tableView.

Here error is of because you're trying to remove a row which is not there in tableView(code not in question).

In case you calling reloadData() it will execute all delegates once again.

Upvotes: 1

Related Questions