首页 > 解决方案 > Firebase Observer 中存储内容的生命周期

问题描述

嗨,我很难在 Firebase 块中获取数组的值

我的代码涉及计算订购的多个食品的数量 (requestFoodItemArray[i]) 并将它们附加到一个数组 (requestFoodNumberArray)。我能够让它成功运行,但是当我尝试在除了 observe() 块之外的任何其他地方访问它时,存储在 requestFoodNumberArray 中的值将会消失。

如何“延长”存储在该特定数组中的数据的寿命?

谢谢!

 override func viewDidLoad() {
    super.viewDidLoad()

    populateCharts(completion: { requestNumberArray in
        print(requestNumberArray)
    })

}

func populateCharts (completion: @escaping (_ requestNumberArray: Array<Double>) -> Void)  {
    for i in 0 ..< requestFoodItemArray.count {
    refRequest.child("\(requestFoodItemArray[i])").observe(.value, with: { snapshot in
        var newItem: [FoodRequestItemList] = []
        for child in snapshot.children {
            if let snapshot = child as? DataSnapshot,
                let requestItemList = FoodRequestItemList(snapshot: snapshot) {
                newItem.append(requestItemList)
            }
        }
        self.item = newItem
        self.requestedItemArray = self.item.map({ $0.key })
        var arrayCount : Double = Double(self.requestedItemArray.count)
        var requestArray : [Double] = []
        requestArray.append(arrayCount)
        completion(requestArray)
    }, withCancel: nil)
}

标签: swiftfirebasefirebase-realtime-database

解决方案


数据从 Firebase 异步加载。在加载数据时,您的其余代码将继续执行。然后当数据可用时,您的闭包 ( snapshot in) 会被调用。

发现requestFoodNumberArray空的代码只是在调用闭包之前运行,因此requestFoodNumberArray仍然是空的。

通过添加一些简单的日志语句,您可以最轻松地看到这一点:

print("Before attaching observer")
refRequest.child("\(requestFoodItemArray[i])").observe(.value, with: { snapshot in
  print("Got data")
})
print("After attaching observer")

如果您运行此代码,您将获得以下输出:

在附加观察者之前

附加观察者后

得到数据

这可能不是您期望数据的顺序。但它确实准确地解释了为什么在闭包之后的代码中数组是空的:数据还没有被加载。

为了不出现这个问题,所有需要数据的代码都必须在闭包内(调用自)。或者(如果您对低级同步感到满意)您可以使用同步原语在关闭等待后进行调用。

看:


推荐阅读