【问题标题】:Modifying array from asynchronous call not modifying the array swift从异步调用修改数组而不是快速修改数组
【发布时间】:2019-05-29 23:02:43
【问题描述】:

我正在尝试使用另一个异步调用的结果来修改我从异步调用中检索到的对象数组。基本上我检索了一个结果数组,并且有一个字段 messages 从我的服务器调用返回 nil。然后,我需要在 for 循环中使用每个 resultid 进行另一个服务器调用,以获取 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
    })

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)")
            }

        }
    }

}

【问题讨论】:

  • 顺便说一句:一种丑陋的数据库架构,对吧?是否可以修复数据的架构方式,而不是在客户端跳过这些障碍?
  • 是的,我想这是可能的。我将不得不考虑重新设计数据库,但目前我想了解为什么这个看似不错的代码行不通。
  • 您的数据库设置是什么?无服务器 NoSQL?
  • 在 Hibernate 中使用 Oracle DB 和 java 后端。
  • 我没有使用 Oracle 数据库的经验,所以我不知道如何最好地利用它们。如果我是你,我会花时间弄清楚如何简化这种数据抓取。可以减少到一个网络调用吗?为什么对非规范化这些数据犹豫不决?

标签: arrays swift asynchronous grand-central-dispatch


【解决方案1】:

我会通过使用一个调度组来简化您的数据处理(因为您只需要一个):

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

        }

    }

}

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

【讨论】:

  • 尝试实现它,我收到以下错误:Incorrect argument label in call (have 'queue:execute:', expected 'queue:work:')dispatchGroup.notify(...)
  • 你使用的是notify(queue: DispatchQueue, work: DispatchWorkItem),而你应该使用notify(queue: DispatchQueue, execute: () -&gt; Void)
  • 或者像你一样使用尾随闭包dispatchGroup.notify(queue: .main) { ... }
  • 我不确定它是否击中了dispatchGroup.notify(...),因为如果我输入print("hello"),则不会打印任何内容
  • 你不是还在使用多个调度组吗?
猜你喜欢
  • 1970-01-01
  • 2021-12-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-01-08
  • 1970-01-01
相关资源
最近更新 更多