gpt4 book ai didi

ios - 如何在 Swift 中创建当前状态?

转载 作者:行者123 更新时间:2023-11-28 05:43:01 24 4
gpt4 key购买 nike

这段代码有问题:

    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
}

在另一个 View Controller 的覆盖函数中调用,日志显示在 viewdidload 的打印中为 0,但在函数打印中显示打印为 30 但始终返回 0,我相信问题是它在进入观察器之前返回,但我不确定是否有任何解决方案?

    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

最佳答案

在我目前正在开发的应用程序中,我遇到了类似的问题。解决方案是在函数中实现一个调度组。我还更改了您的函数返回 total 的方式,以便它现在由完成处理程序返回。

试试这个:

 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 返回总数。

由于您使用 calculaGastos 的方式,completionHandler 也很有用。您正在调用该函数,然后使用要在文本字段中显示的返回值。现在添加了完成处理程序,textField.text 仅在 calculaGastos 完成并返回 total 后设置:

calculo.calculaGastos { (total) in
print("calculaGastos total: \(total)")
gastosField.text = String(total)
benefField.text = String(calculo.calculaBenef())
}

希望这是有道理的!很高兴代码对你有用。

关于ios - 如何在 Swift 中创建当前状态?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55925401/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com