【问题标题】:What happens if I put Dispatch.main.async block inside Dispatch.global.async?如果我将 Dispatch.main.async 块放入 Dispatch.global.async 会发生什么?
【发布时间】:2018-11-16 14:40:26
【问题描述】:

我有一个案例,我在后台线程中的 Dispatch.global 中将数据保存到 Realm 数据库,然后在同一个线程中我调用 Dispatch.main.async 从 Realm 获取数据并更新 UITableView 数据。

问题是我获得的数据数量较少(data.count)。假设总数据数为 10,那么有时我会得到所有数据,有时会少于 10。

为什么会这样?

下面是示例代码sn-p

func getData(data: [String]) {
    DispatchQueue.global(qos: .background).async {
        RealmManager.removeDataFromRealm()
        RealmManager.saveDataToRealm(data)
        Dispatch.main.async {
            let dataFromRealm = RealmManager.getDataFromRealm()
            self.sendDataToUI(dataFromRealm)
        }
    }
}

在上面的代码中 removeDataFromRealm()、saveDataToRealm(data)、getDataFromRealm() 是领域类静态函数,我在其中保存、删除、从领域数据库中获取数据

我已经从我理解的所有方面调试了代码,它保存 (saveDataToRealm(data)) 所有数据,然后获取 (getDataFromRealm()) 数据,根据我的理解为什么它发送给我的数量更少数据有时

在获取数据时,RealmManager getDataFromRealm() 静态方法没有应用过滤器。

假设上面的代码进入竞争状态,那么下面的代码 sn-p 会发生什么

    func getImageFromServer (url: URL) {
        DispatchQueue.global(qos: .background).async {
            do {
                let data = try Data(contentsOf: url)
                DispatchQueue.main.async {
                    self.imageView.image = UIImage(data: data)
                }
            }catch {
                print(error)
            }
        }
    }

由于 getImageFromServer() 首先获取数据,然后 Dispatch.main.async 在将“Data(contentsOf: url)”转换为显然需要时间的数据后执行。

为什么在上述情况下它的工作方式不同?

【问题讨论】:

  • 您的领域调用可能都非常耗时,这意味着您的提取是在保存完成之前启动的。
  • RealmManager.removeDataFromRealmRealmManager.saveDataToRealm的实现是异步的还是同步的?
  • @RakeshShastri 我调试了代码并根据调试断点删除数据然后保存数据然后获取数据..
  • @rmaddy 据我了解,Realm 库是异步工作的。我的方法实现是同步的
  • RealmManager.saveDataToRealm(data) 是异步函数吗?我的意思是在 saveDataToRealm 内部是否有任何操作异步执行?

标签: swift realm grand-central-dispatch dispatch-async dispatch-queue


【解决方案1】:

如果您的RealmManager.removeDataFromRealm() 和/或RealmManager.saveDataToRealm(data) 是异步的,那么您在这里陷入了竞争状态,因为在执行DispatchQueue.main 中的代码之前无法保证您的数据已保存。可以用DispatchGroup等待以上两种方法完成后再输入DispatchQueue.main.async

回答标题中的问题,如果你在全局队列中,然后在全局队列中执行代码,那么swift所做的本质上就是从前者切换到后者。

【讨论】:

  • 请检查我编辑的问题,感谢您的回答谢谢
猜你喜欢
  • 1970-01-01
  • 2014-02-06
  • 2011-03-19
  • 2010-12-02
  • 1970-01-01
  • 1970-01-01
  • 2015-07-15
  • 2010-12-12
  • 2019-09-10
相关资源
最近更新 更多