arrays - 从异步调用修改数组不会快速修改数组

标签 arrays swift asynchronous grand-central-dispatch

我正在尝试使用另一个异步调用的结果来修改从异步调用中检索的对象数组。基本上,我检索结果数组,并且有一个从服务器调用返回 nil 的字段 messages 。然后,我需要在 for 循环中使用每个 resultid 进行另一个服务器调用,以获取 messages 数组。然后,我将 messages 设置为返回值。

大约 20 分钟前,我刚刚从 https://stackoverflow.com/a/48718976/3272438 了解到如何使用 DispatchGroup() ,所以请耐心等待。

我遇到的问题是,当我执行 print("C0: (self.res)") 时,它会打印出所有项目,包括 messages 我只是添加。当 print("C2: (self.res)")group.notify(...) 中打印时,所有消息字段打印出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
    })

ViewController.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
            })

        }

    }

}

这只是一个起点。如果这是生产代码,我将实现错误处理和后台排队(假设数据在主线程上返回)。

关于arrays - 从异步调用修改数组不会快速修改数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56369592/

相关文章:

C# 数组或 List(T) 以获得最佳性能

swift - 在工作表中使用 NavigationLink 后的两个 UINavigationController

swift - 向动态标签添加字符串属性

c# - 异常在异步代码块中被忽略

Javascript SignalR 等到服务广播所有消息

c - C语言读取一个TXT文件中的所有字符

c - 在C中删除动态分配的数组成员

ios - SKaction 阻止了 touchesBegan 事件

python - 如何在 python 代码段上应用并行或异步 I/O 文件写入

arrays - 获取postgresql表中jsonb对象的所有键,其中值为true