我在从 swift 到 firebase 的查询中遇到问题。下面是我在 firebase 中的示例 JSON:
Lulibvi-d220
Contas
-KwlPQZTqVfNhHAsFyW5
Nome: "Assets"
Numero: "1"
-KwlGJLUTqVfnhYHAsFyW5
Nome: "Liabilities"
Numero: "2"
我的代码如下:
let nome: String = "Liabilities"
let numero: String = "2"
ref = Database.database().reference()
ref.child("Contas").child("Assets").observeSingleEvent(of: .value) { (snapshot) in
let numero = (snapshot.value as? NSDictionary)?["Numero"] as? String
print (numero as Any)
}
调试时,调试器只是将(快照)之后的所有代码都跳转进去,并不执行。
我做错了什么?
谢谢
tl;dr:要在 XCode 中调试异步代码,请在完成处理程序内的第一条语句上放置一个断点。
更长的解释:
当您观察来自 Firebase 的值时,获取该数据可能需要任何时间。为防止您的程序在此期间被阻止,在您的代码继续运行的同时,数据会在后台从 Firebase 数据库加载。然后,当数据可用时,Firebase 会调用您的完成处理程序。
这种模式称为异步加载,几乎适用于所有现代 Web API。但要习惯它可能非常困难。
查看发生了什么的一种简单方法是使用一些适当的日志记录语句运行代码:
ref = Database.database().reference()
print("Before attaching observer")
ref.child("Contas").child("Assets").observeSingleEvent(of: .value) { (snapshot) in
print("Inside completion handler")
}
print("After attaching observer")
此代码将立即打印:
附加观察者之前
附加观察者后
然后过了一会儿(取决于网络速度和其他因素):
内部完成处理程序
虽然有一些方法可以让代码在块之后等待数据(有关更多信息,请参阅下面的一些链接),但处理异步加载的更常见方法是重新构建问题。不要尝试编写“首先获取数据,然后打印它”的代码,而是将您的问题定义为“我们开始获取数据。每当我们获取数据时,我们就打印它”。
将其建模为代码的方法是将所有需要访问来自 Firebase 的数据的代码移动到观察者的完成处理程序中。您的代码已经通过print (numero as Any)
在那里做到了这一点。
要在 XCode 中调试异步代码,请在完成处理程序内的代码上放置一个断点。当数据从 Firebase 返回时,该断点将被击中。
一些问题也涉及这种行为:
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句