arrays - 从异步调用修改数组而不是快速修改数组
问题描述
我正在尝试使用另一个异步调用的结果来修改我从异步调用中检索到的对象数组。基本上我检索了一个结果数组,并且有一个messages
从我的服务器调用返回 nil 的字段。然后,我需要在 for 循环中使用每个id进行另一个服务器调用以获取数组。然后我将 设置为返回值。 result
messages
messages
大约 20 分钟前,我刚刚从https://stackoverflow.com/a/48718976/3272438了解到使用DispatchGroup(),所以请耐心等待。
我遇到的问题是,当我执行print("C0: (self.res)")时,它会打印出所有项目,包括messages
我刚刚添加的项目。当print("C2: (self.res)")在 中打印时group.notify(...)
,所有messages
字段都打印出nil。我被难住了,我已经尝试了我能想到的一切。任何帮助将非常感激。
更新 通过更改以下 group.notify() 永远不会被调用
Service.getMessages(resultId: self.res![index].id, completionHandler: { (latestMessage, response, error) in
if let latestMessage = latestMessage {
self.res![index].messages = [latestMessage]
print("L2: \(self.res![index].messages)")
print("C0: \(self.res)")
}
group.leave() // continue the loop
})
视图控制器.Swift
var res: [ResultDTO]?
override func viewDidLoad() {
super.viewDidLoad()
let group0 = DispatchGroup()
group0.enter()
Service.getResults { (results, response, error) in
guard var results = results else { print("PROBLEM"); return }
self.res = results
group0.leave()
}
group0.notify(queue: .main) {
print("in group0")
let group = DispatchGroup() // initialize
for index in 0..<self.res!.count {
group.enter() // wait
Service.getMessages(resultId: self.res![index].id, completionHandler: { (latestMessage, response, error) in
if let latestMessage = latestMessage {
self.res![index].messages = [latestMessage]
print("L2: \(self.res![index].messages)")
print("C0: \(self.res)")
}
})
group.leave() // continue the loop
}
group.notify(queue: .main) {
print("In group notify")
do {
print("C2: \(self.res)")
for index in 0..< self.res!.count {
print("L4: \(self.res![index].messages)")
}
// ... configure my view with the data
} catch {
print("Error: \(error)")
}
}
}
}
解决方案
我会通过使用一个调度组来简化您的数据处理(因为您只需要一个):
class YourViewController: UIViewController {
private var results: [ResultDTO]?
override func viewDidLoad() {
super.viewDidLoad()
getResults()
}
private func getResults() {
Service.getResults { (results, response, error) in
guard let results = results,
results.count > 0 else {
return
}
let dispatchGroup = DispatchGroup()
for r in results {
dispatchGroup.enter()
Service.getMessages(resultId: r.id, completionHandler: { (latestMessage, response, error) in
if let latestMessage = latestMessage {
r.messages = [latestMessage]
}
dispatchGroup.leave()
}
}
dispatchGroup.notify(queue: .main, execute: {
self.results = results
})
}
}
}
认为这只是一个起点。如果这是生产代码,我将实现错误处理和后台排队(假设数据在主线程上返回)。
推荐阅读
- wordpress - wordpress 将 URl 重新指向 WP 目录
- django - Django 消息历史
- javascript - 调用 setState 时,React-Redux 连接的组件无法更新视图/触发重新渲染
- r - 使用 RSelenium 和日历格式选择日期
- asp.net-mvc - 如何在.NET核心中临时存储表单数据
- sql - 具有相同表数据 SQL Server 的多个联接
- spring - 版本健全性检查 (Spring/SLF4J)
- fabricjs - 如何在 Fabric.js 中缩放图像以忽略纵横比?
- c# - Power Bi 在 .NET 4.8 下使用 c# 发布带有服务主体的报告
- apache-spark-sql - Databricks/Spark SQL - 如何在地图类型字段中获取数据