【问题标题】:Index Out of Range when deleting from TableView?从 TableView 删除时索引超出范围?
【发布时间】:2016-08-31 00:38:20
【问题描述】:

提醒一下,我正在使用 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 方法之后我得到了错误。在这里呆了一段时间,似乎无法找到它。此外,我始终确保数组与数据库和数组匹配,以便在填充它们之前它们同时为空。

【问题讨论】:

  • 在您的删除功能上删除此代码self.tableView.reloadData()。因为删除后tableview 更新了自己。检查print(currentName) 会给你一个想法。
  • 啊那没用,但我会打印它以跟踪我的 currentName

标签: ios swift uitableview firebase


【解决方案1】:

使用 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)

【讨论】:

  • 啊,这很有道理。非常有见地,非常感谢!这正是我所需要的
【解决方案2】:

我认为您必须在发货前移动这些行

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-07-11
    • 1970-01-01
    • 2021-11-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多