【问题标题】:The lifespan of stored content inside Firebase ObserverFirebase Observer 中存储内容的生命周期
【发布时间】:2019-05-24 10:25:41
【问题描述】:

您好,我很难在 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)
}

【问题讨论】:

    标签: swift firebase firebase-realtime-database


    【解决方案1】:

    数据是从 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")
    

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

    附加观察者之前

    附加观察者后

    得到数据

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

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

    见:

    【讨论】:

    • 感谢您的建议!我试图实现一个完成处理程序 - 请参阅更新的代码,但由于某种原因,append(arrayCount) 之后的 requestArray 仍然只返回一个双精度值而不是整个数组。不知道我做错了什么?请帮忙!谢谢~
    • 您添加到requestArray 的所有内容都是一个计数:requestArray.append(arrayCount),这就是完成处理程序中可用的所有内容。您确定不希望将 newItem 传递给完成处理程序吗?
    • 我正在尝试使用 for 循环遍历“requestFoodItemArray”中列出的所有食物项目,并使用“var arrayCount : Double = Double(self.requestedItemArray.count)”获取它们各自的编号然后将此附加到 requestArray 以便我可以使用数组数据来填充图表。不确定如何为图表准备好一组完整的数字?如果图表在闭包之外,由于异步性质,它不会获得任何数据。如果在闭包内调用图表,则循环性质意味着它只有一个可用的数字。
    • 是的,那里发生了很多事情。我建议在调试器中运行您的代码并设置一些断点。例如,您现在似乎为您加载的每个子节点调用completion(requestArray),这意味着您每次都用一个数字调用它。您可能只想使用所有数字调用它一次,但这不是您的代码所做的。
    猜你喜欢
    • 2020-07-30
    • 2012-08-27
    • 1970-01-01
    • 1970-01-01
    • 2015-12-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多