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

时间:2016-08-31 00:38:21

标签: ios swift uitableview firebase

我正在使用Firebase存储/删除数据。

这是我的viewDidLoad代码:

 override func viewDidLoad()
{
    super.viewDidLoad()

    observePeople()

    tableView.delegate = self
    tableView.dataSource = self

}

observePeople()方法就像这样运行(我在这里重新加载表两次)

 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)
}

在我的viewDidAppear中,我再次刷新表格:

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

最后,我删除了行,我得到的错误是索引超出范围。有趣的是,当我用4个项目填充表格时,如果我删除了第一个项目,它实际上会删除第二个项目,如果我删除第三个项目,它实际上会删除第四个项目,所以上。我一直在添加断点来尽我所能地观察这种现象,并且在我从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)
    }
}

因此,在tableView.deleteRows方法之后,我收到错误。已经有一段时间了,似乎无法找到它。此外,我总是确保数组与数据库和数组匹配,以便在填充它们之前它们同时为空。

2 个答案:

答案 0 :(得分:2)

使用firebase会改变您通常使用表的方式。您可能认为必须从数组中删除然后从tableView中删除行,因为这是我们在大多数情况下对数组数据执行的操作,但这样做会导致firebase查询或侦听时出现问题。处理此问题的最佳方法是不在commitEditingStyle函数中手动删除数组或表中的任何数据。而只是从firebase中删除值。然后在.ChildRemoved的监听器中从数据数组中删除对象并重新加载表。

删除

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

并在.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)

答案 1 :(得分:0)

我认为你必须在发货前移动这些线

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