Swift 3,Firebase 完成 Handler 执行两次

Posted

技术标签:

【中文标题】Swift 3,Firebase 完成 Handler 执行两次【英文标题】:Swift 3, Firebase completion Handler is executed twice 【发布时间】:2017-09-03 21:09:39 【问题描述】:

我的用例 - 我有从 Firebase 获取的项目列表。下面是我从 HomeViewController 调用的 loadItems() 函数 - viewDidLoad() 并使用获取的数据更新 tableView。

func loadItems() 

    Database.database().reference().child("items").observe(.value, with:  snapshot in
        var fetchedItems = [Item]()
        guard let receivedvalue = snapshot.value as? [String: Any] else     
            print("Received null")
            return
        
        print(receivedvalue)

        for (key, value) in receivedvalue 
            let item = Item(id: Int(key)!, json: value as! [String : Any])
            fetchedItems.append(item!)
        
        self.items = fetchedItems
        self.tableView.reloadData()
    )

我正在保存一个项目并从 CreateViewController 返回到 HomeViewController,我正在 - 将项目保存在 Firebase 中,将项目附加到预取数组,重新加载 tableView。

func addItem(item: Item?) 
    rootRef = Database.database().reference()

    let id = String(describing: item.id!)
    let itemRef = self.rootRef.child("items").child(id)
    itemRef.setValue(["name": item.name!, "type": item.type!])

    items.append(item!)
    self.tableView.reloadData()

重新加载 tableView 后,它会进入 loadItems() 中的 Firebase GET 调用处理程序。

当我在 viewDidLoad() 期间获取所有项目时,处理程序会执行一次。即使我没有在创建工作流中调用 loadItems(),是否有任何理由第二次执行 Firebase GET 调用处理程序?

【问题讨论】:

当你从 CreateViewController 回来时你的 viewDidLoad 会被调用吗? 如果使用addItem函数向items节点添加一个项目,那么该节点的值会发生变化,因此会再次执行闭包。 @JenPerson 是的,在使用 observeSingleEvent 之后,闭包只执行一次。问题解决了。谢谢! 【参考方案1】:

当使用 .observe(.value 时,它会向该节点添加一个观察者,并且 任何 对该节点的更改(添加、更改、删​​除)都会触发代码在闭包中。

如果您想离开观察者以便收到更改通知,正确的流程是简单地将数据写入 Firebase 并让闭包加载数据并填充 tableView。

但是,这样做的缺点是 .value 会加载节点中的所有数据。您可能想看看为 .childAdded、.childChanged 和 .childRemoved 添加单独的观察者。那些只会加载被修改的节点。

如果您只想加载一次数据(例如在启动时填充数据源),请使用会触发一次且不会留下观察者的 observeSingleEvent。

然后将数据存储在 Firebase 中并手动将其添加到数组中并重新加载 tableView。

请参阅文档Read Data Once 部分。

【讨论】:

使用observeSingleEvent,闭包只执行一次。感谢您的详细解释!

以上是关于Swift 3,Firebase 完成 Handler 执行两次的主要内容,如果未能解决你的问题,请参考以下文章

Firebase Swift 3 完成处理程序 Bool

Firebase 和 Swift:异步调用、完成处理程序

使用 Firebase 的 Swift 完成处理程序

Swift/iOS - Firebase 远程配置获取值永远不会完成

如何使用 swift 和 firebase 正确使用完成处理程序?

Swift 中的完成处理程序 Firebase 观察者