简体   繁体   English

从TableView删除时索引超出范围?

[英]Index Out of Range when deleting from TableView?

Just as a heads up I am using Firebase to store/remove data. 正如提醒我一样,我正在使用Firebase来存储/删除数据。

Here is my viewDidLoad code: 这是我的viewDidLoad代码:

 override func viewDidLoad()
{
    super.viewDidLoad()

    observePeople()

    tableView.delegate = self
    tableView.dataSource = self

}

The observePeople() method operates like this (I reload the table twice here) watchPeople()方法的工作方式如下(我在这里两次重载了表)

 func observePeople()
{
    let ref = FIRDatabase.database().reference().child("Users")
    ref.observeEventType(.ChildAdded, withBlock:
    { (snapshot) in

        if let firstname = snapshot.value?.objectForKey("firstname"), lastname = snapshot.value?.objectForKey("lastname")
        {
            let fullname = "\(firstname) \(lastname)"
            self.names.append(fullname)

            dispatch_async(dispatch_get_main_queue())
            {
                self.tableView.reloadData()
            }
        }

    }, withCancelBlock: nil)

    ref.observeEventType(.ChildRemoved, withBlock:
    { (snapshot) in

    if let firstname = snapshot.value?.objectForKey("firstname"), lastname = snapshot.value?.objectForKey("lastname"), dateOfBirth = snapshot.value?.objectForKey("Date of Birth"), zipcode = snapshot.value?.objectForKey("Zipcode")
    {
        print("We deleted the person \(firstname) \(lastname) with the details: \(dateOfBirth), \(zipcode)")
        self.tableView.reloadData()
    }

    }, withCancelBlock: nil)
}

And in my viewDidAppear I refresh the table again: 在我的viewDidAppear中,我再次刷新表:

override func viewDidAppear(animated: Bool)
{
    tableView.reloadData()
}

Lastly, I once I delete the row I get the error saying the index is out of range. 最后,删除行后,出现错误消息,指出索引超出范围。 What is interesting is when I populate my table with 4 items, if I delete the first item it'll ACTUALLY delete the second item, and if i delete the third one it'll actually delete the fourth one, and so on. 有趣的是,当我在表中填充4个项目时,如果删除第一个项目,它将实际上删除第二个项目;如果删除第三个项目,则实际上将删除第四个项目,依此类推。 I've been adding breakpoints to observe this phenomenon the best I can and it breaks right after I remove it from the tableview. 我一直在添加断点,以尽我所能观察这种现象,并将其从表视图中删除后立即中断。

override func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath)
{
    if editingStyle == .Delete
    {
        let ref = FIRDatabase.database().reference().child("Users")
        ref.observeEventType(.ChildAdded, withBlock: { (snapshot) in

            if let firstname = snapshot.value?.objectForKey("firstname"), lastname = snapshot.value?.objectForKey("lastname")
            {
                let fullname = "\(firstname) \(lastname)"
                let currentName = self.names[indexPath.row]

                if fullname == currentName
                {
                    print("We have a match")
                    let currentKey = snapshot.key
                    ref.child(currentKey).removeValue()

                    dispatch_async(dispatch_get_main_queue())
                    {
                        self.tableView.reloadData()
                    }
                }

            }

            }, withCancelBlock: nil)
    }

        names.removeAtIndex(indexPath.row)
        tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: .Fade)
    }
}

So right after the tableView.deleteRows method I'm getting the error. 所以在tableView.deleteRows方法之后,我得到了错误。 Been at this for a while and can't seem to locate it. 已经有一段时间了,似乎找不到它。 Also, I always make sure the arrays match up for the database and the array so they're both empty at the same time before I populate them. 另外,我总是确保数组与数据库和数组匹配,因此在填充它们之前它们都同时为空。

Working with firebase changes how you generally work with tables. 使用Firebase会更改通常使用表的方式。 You may think you have to delete from the array and then delete the rows from the tableView because thats what we do with array data for most cases, but in doing so it causes problems when firebase is querying or listening. 您可能认为您必须从数组中删除,然后从tableView中删除行,因为多数情况下多数民众赞成在大多数情况下对数组数据进行处理,但是这样做会在firebase查询或侦听时引起问题。 The best way to handle this is not to delete any data from arrays or the table manually in the commitEditingStyle function. 解决此问题的最佳方法是不要在commitEditingStyle函数中从数组或表中手动删除任何数据。 Instead only remove the value from firebase. 而是仅从Firebase中删除该值。 Then in your listener for .ChildRemoved remove the object from the array of data and reload the table. 然后在您的.ChildRemoved侦听器中,从数据数组中删除该对象并重新加载表。

Delete 删除

  names.removeAtIndex(indexPath.row)
  tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: .Fade)

And Insert the removal of the name in your .ChildRemoved listener 并在您的.ChildRemoved侦听器中插入名称的删除

ref.observeEventType(.ChildRemoved, withBlock:
{ (snapshot) in

if let firstname = snapshot.value?.objectForKey("firstname"), lastname = snapshot.value?.objectForKey("lastname"), dateOfBirth = snapshot.value?.objectForKey("Date of Birth"), zipcode = snapshot.value?.objectForKey("Zipcode")
{
    print("We deleted the person \(firstname) \(lastname) with the details: \(dateOfBirth), \(zipcode)")
    let fullname = "\(firstname) \(lastname)"
    if let index = names.indexOf(fullname) {
       names.removeAtIndex(index)
       self.tableView.reloadData()
    }
}

}, withCancelBlock: nil)

i think you have to move these lines before you despatch 我认为您必须在发送之前移动这些行

    names.removeAtIndex(indexPath.row)
    tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: .Fade)

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

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