gpt4 book ai didi

Swift - 在调用完成处理程序 swift 之前等待异步 for-in 循环完成

转载 作者:可可西里 更新时间:2023-11-01 00:54:17 24 4
gpt4 key购买 nike

我对实现此目标的最佳方法感到困惑。我正在尝试通过网络调用保留我正在循环并加在一起的 Double 值的总和。我读过的所有内容都说要使用 DispatchGroup。我的完成要么调用得太早,要么根本没有被调用,我已经尝试了我能想到的 .enter、.leave 和 .wait 的所有配置。

    let group = DispatchGroup()
var runningTotal: Double = 0.00

ref.observeSingleEvent(of: .value) { (snapshot) in
guard let bills = snapshot.value as? [String: AnyObject] else {
//error
return
}

for billId in bills.keys {
group.enter()
print("Entering")
Database.database().reference().child("bills").child(billId).observeSingleEvent(of: .value, with: { (snapshot) in
guard let bill = snapshot.value as? [String: AnyObject] else {
return
}
if let amount = bill["amount"] as? Double {
runningTotal += amount
}
group.leave()
print("Leaving")
})
}
completion(runningTotal)
}
group.wait()
}

最佳答案

几个想法:

  1. 避免从主线程调用wait。其用例非常有限。 notify 是实现相同目的的更安全的方法。

  2. 确保从循环中的每个路径调用 leave。这可以通过 defer block 很好地实现。

所以:

func foo(completion: @escaping (Double?) -> Void) {
ref.observeSingleEvent(of: .value) { snapshot in
guard let bills = snapshot.value as? [String: AnyObject] else {
//error
completion(nil)
return
}

let group = DispatchGroup()
var runningTotal = 0.0

for billId in bills.keys {
group.enter()
print("Entering")
Database.database().reference().child("bills").child(billId).observeSingleEvent(of: .value) { snapshot in
defer { group.leave() }
guard let bill = snapshot.value as? [String: AnyObject] else {
return
}
if let amount = bill["amount"] as? Double {
runningTotal += amount
}
print("Leaving")
}
}
group.notify(queue: .main) {
completion(runningTotal)
}
}
}

关于Swift - 在调用完成处理程序 swift 之前等待异步 for-in 循环完成,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54300037/

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