swift - 如果我将 Dispatch.main.async block 放在 Dispatch.global.async 中会发生什么?

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

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

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

为什么会这样?

以下是示例代码片段

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() 是 Realm 类静态函数,我在其中保存、删除、从 Realm 数据库获取数据

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

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

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

    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.removeDataFromRealm() 和/或 RealmManager.saveDataToRealm(data) 是异步的,那么您已经陷入竞争状态,因为没有任何保证在执行 DispatchQueue.main 中的代码之前保存您的数据。你可以做的是使用 DispatchGroup 等待上面的两个方法完成,然后再进入 DispatchQueue.main.async

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

关于swift - 如果我将 Dispatch.main.async block 放在 Dispatch.global.async 中会发生什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53339971/

相关文章:

objective-c - 将 Objective-C 代码转换为 Swift

javascript - 如何在 Realm 数据库中保存数据javascript

ios - View 重新出现时刷新表内容

swift - 从类中调用函数

swift - 在 Realm 数据库中创建并更新现有元素时出现问题

java - 在Realmchangelistener中调用listview的notifydatasetchanged()好不好?

ios - 回调CFNetwork线程

macos - 在 Linux 中使用大中央调度

ios - GCD 没有获取网络内容来获取部署在 Internet 上的字符串

ios - 属性初始值设定项在 'self' 可用错误 Swift 之前运行