如何在Swift的时刻进行观察?
How to make an observe at the moment in Swift?
我在这段代码中遇到问题:
func calculaGastos() -> Float{
let idUser = Auth.auth().currentUser?.displayName
var total : Float = 0
let ref = Database.database().reference().child("Users").child(idUser!).child("Gastos")
ref.observeSingleEvent(of: .value) { (snapshot) in
let value = snapshot.value as? NSDictionary
if(value != nil){
for i in value!{
let j = i.value as? NSDictionary
let precio = j?["precio"] as? Float
let fecha = j?["Fecha"] as? String
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "MMM d, yyyy"
let date = dateFormatter.date(from: fecha!)
if(((date?.timeIntervalSinceNow)! * -1) < (30*24*3600)){
print("Total:" ,total)
total += precio!
}
}
}
print("Calculing in the function", total)
}
return total
}
在另一个视图控制器的覆盖函数中调用,日志显示在 viewdidload 的打印中为 0,但在函数打印中显示为 30,但 return 全部为 0时间,我认为问题在于它 returns 在进入观察器之前,但我不确定是否有任何解决方案?
override func viewDidLoad() {
super.viewDidLoad()
nomUser.text = id?.displayName!
correoLabel.text = id?.email!
print("Calculing in View Controller", calculo.calculaBenef(), calculo.calculaGastos())
gastosField.text = String(calculo.calculaGastos())
benefField.text = String(calculo.calculaBenef())
// Do any additional setup after loading the view.
}
这是我的日志:
Log
在我目前正在开发的应用程序中,我 运行 遇到了类似的问题。解决方案是在函数中实现一个调度组。我还更改了函数 returns total
的方式,以便它现在由完成处理程序 returned。
试试这个:
func calculaGastos(completionHandler: @escaping (Float) -> Void){
let idUser = Auth.auth().currentUser?.displayName
var total : Float = 0
let ref = Database.database().reference().child("Users").child(idUser!).child("Gastos")
ref.observeSingleEvent(of: .value) { (snapshot) in
let value = snapshot.value as? NSDictionary
if(value != nil){
let myGroup = DispatchGroup()
for i in value!{
myGroup.enter()
let j = i.value as? NSDictionary
let precio = j?["precio"] as? Float
let fecha = j?["Fecha"] as? String
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "MMM d, yyyy"
let date = dateFormatter.date(from: fecha!)
if(((date?.timeIntervalSinceNow)! * -1) < (30*24*3600)){
print("Total:" ,total)
total += precio!
}
myGroup.leave()
}
myGroup.notify(queue: .main) {
print("Calculing in the function", total)
completionHandler(total)
}
}}
}
调用函数并像这样使用 total
:
override func viewDidLoad() {
super.viewDidLoad()
nomUser.text = id?.displayName!
correoLabel.text = id?.email!
print("Calculing in View Controller", calculo.calculaBenef())
calculo.calculaGastos { (total) in
print("calculaGastos total: \(total)")
gastosField.text = String(total)
benefField.text = String(calculo.calculaBenef())
}
// Do any additional setup after loading the view.
}
据我了解:
observeSingleEvent
是异步的,因此在调用 return
时它可能完成也可能不完成。此外,for i in value
仅在 observeSingleEvent
完成后启动,因此 return
更有可能在任务完成之前被调用。这就是 DispatchGroup()
和完成处理程序进来的地方。
当调用myGroup.enter()
时,它通知DispatchGroup一个任务已经开始。当 myGroup.leave()
被调用时,DispatchGroup 被通知任务已经完成。一旦 .leave()
与 .enter()
一样多,该组就结束了。然后 myGroup
通知主队列该组已完成,然后 completionHandler
被调用,总共 returns。
由于您使用的方式,completionHandler 也很有用 calculaGastos
。您正在调用该函数,然后使用要在文本字段中显示的 return 值。现在添加了完成处理程序,textField.text
仅在 calculaGastos
完成并且 returned total
:
之后才被设置
calculo.calculaGastos { (total) in
print("calculaGastos total: \(total)")
gastosField.text = String(total)
benefField.text = String(calculo.calculaBenef())
}
希望这是有道理的!很高兴代码对你有用。
我在这段代码中遇到问题:
func calculaGastos() -> Float{
let idUser = Auth.auth().currentUser?.displayName
var total : Float = 0
let ref = Database.database().reference().child("Users").child(idUser!).child("Gastos")
ref.observeSingleEvent(of: .value) { (snapshot) in
let value = snapshot.value as? NSDictionary
if(value != nil){
for i in value!{
let j = i.value as? NSDictionary
let precio = j?["precio"] as? Float
let fecha = j?["Fecha"] as? String
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "MMM d, yyyy"
let date = dateFormatter.date(from: fecha!)
if(((date?.timeIntervalSinceNow)! * -1) < (30*24*3600)){
print("Total:" ,total)
total += precio!
}
}
}
print("Calculing in the function", total)
}
return total
}
在另一个视图控制器的覆盖函数中调用,日志显示在 viewdidload 的打印中为 0,但在函数打印中显示为 30,但 return 全部为 0时间,我认为问题在于它 returns 在进入观察器之前,但我不确定是否有任何解决方案?
override func viewDidLoad() {
super.viewDidLoad()
nomUser.text = id?.displayName!
correoLabel.text = id?.email!
print("Calculing in View Controller", calculo.calculaBenef(), calculo.calculaGastos())
gastosField.text = String(calculo.calculaGastos())
benefField.text = String(calculo.calculaBenef())
// Do any additional setup after loading the view.
}
这是我的日志: Log
在我目前正在开发的应用程序中,我 运行 遇到了类似的问题。解决方案是在函数中实现一个调度组。我还更改了函数 returns total
的方式,以便它现在由完成处理程序 returned。
试试这个:
func calculaGastos(completionHandler: @escaping (Float) -> Void){
let idUser = Auth.auth().currentUser?.displayName
var total : Float = 0
let ref = Database.database().reference().child("Users").child(idUser!).child("Gastos")
ref.observeSingleEvent(of: .value) { (snapshot) in
let value = snapshot.value as? NSDictionary
if(value != nil){
let myGroup = DispatchGroup()
for i in value!{
myGroup.enter()
let j = i.value as? NSDictionary
let precio = j?["precio"] as? Float
let fecha = j?["Fecha"] as? String
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "MMM d, yyyy"
let date = dateFormatter.date(from: fecha!)
if(((date?.timeIntervalSinceNow)! * -1) < (30*24*3600)){
print("Total:" ,total)
total += precio!
}
myGroup.leave()
}
myGroup.notify(queue: .main) {
print("Calculing in the function", total)
completionHandler(total)
}
}}
}
调用函数并像这样使用 total
:
override func viewDidLoad() {
super.viewDidLoad()
nomUser.text = id?.displayName!
correoLabel.text = id?.email!
print("Calculing in View Controller", calculo.calculaBenef())
calculo.calculaGastos { (total) in
print("calculaGastos total: \(total)")
gastosField.text = String(total)
benefField.text = String(calculo.calculaBenef())
}
// Do any additional setup after loading the view.
}
据我了解:
observeSingleEvent
是异步的,因此在调用 return
时它可能完成也可能不完成。此外,for i in value
仅在 observeSingleEvent
完成后启动,因此 return
更有可能在任务完成之前被调用。这就是 DispatchGroup()
和完成处理程序进来的地方。
当调用myGroup.enter()
时,它通知DispatchGroup一个任务已经开始。当 myGroup.leave()
被调用时,DispatchGroup 被通知任务已经完成。一旦 .leave()
与 .enter()
一样多,该组就结束了。然后 myGroup
通知主队列该组已完成,然后 completionHandler
被调用,总共 returns。
由于您使用的方式,completionHandler 也很有用 calculaGastos
。您正在调用该函数,然后使用要在文本字段中显示的 return 值。现在添加了完成处理程序,textField.text
仅在 calculaGastos
完成并且 returned total
:
calculo.calculaGastos { (total) in
print("calculaGastos total: \(total)")
gastosField.text = String(total)
benefField.text = String(calculo.calculaBenef())
}
希望这是有道理的!很高兴代码对你有用。