使用调度组时如何使公共资源线程安全?

帕万

我有一个User类,每次用户打开应用程序时都需要更新

class User : NSObject, NSCoding {
    var vehicles : [Vehicles]
    var bankaccounts : [BankAccounts]
    var friends : [Friends]
}

在主屏幕ViewController中,我有一个使用3个Alamofire请求从后端获取数据的函数。最后,我将数据保存在UserDefaults中。DispatchGroup是实现此目标的第一件事。这是代码

func loadUserData {
    var user = User()

    let userDataDispatchGroup = DispatchGroup()

    userDataDispatchGroup.enter()
    AF.request(...).responseJSON {
        //update the user.vehicles array
        userDataDispatchGroup.leave()
    }
    
    userDataDispatchGroup.enter()
    AF.request(...).responseJSON {
        //update the user.bankaccounts array
        userDataDispatchGroup.leave()
    }

    userDataDispatchGroup.enter()
    AF.request(...).responseJSON {
        //update the user.friends array
        userDataDispatchGroup.leave()
    }

    userDataDispatchGroup.notify(queue: .main) {
        let encodedData  = NSKeyedArchiver.archivedData(withRootObject: user)
        UserDefaults.standard.set(encodedData, forKey: "user")
    }

}

但是我不清楚用户对象的线程安全性。由于它将在三个不同的回调中进行更新,因此线程安全在这里会成为问题吗?如果是,解决问题的最佳方法是什么?我当时在考虑使用DispatchSemaphore。但是我不确定这是否正确。

你问:

但是我不清楚用户对象的线程安全性。由于它将在三个不同的回调中进行更新,因此线程安全在这里会成为问题吗?

您的代码段中没有线程安全问题,因为Alamofire在主线程上调用其完成处理程序。他们这样做是为了缓解多线程问题。DispatchQueue.main.async在这种情况下,不需要任何操作如Alamofire文档所述

.main默认情况下,传递到响应处理程序的闭包在队列上执行,但是DispatchQueue可以传递特定的内容来执行闭包。

因此,除非您进行了不寻常的操作(例如,.main使用一些并发来覆盖默认队列DispatchQueue),否则Alamofire将在主线程上运行其完成处理程序,从而减轻了线程安全性的顾虑。

如果您使用的另一个API没有在主线程上调用其完成处理程序(例如URLSession.shared,在后台队列上调用其完成处理程序),则可能会有所顾虑,但Alamofire则不会。(甚至URLSession使用串行后台队列,因此使用模式更新本地变量时不会出现问题。)

最重要的是,只要您不同时从多个线程中更改/访问一个变量,就可以大大缓解线程安全问题。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

多线程。如何平等地共享公共资源?

片段之间如何共享公共资源?

如何在两个线程之间共享公共资源?

如何为几个项目使用公共资源(项目依赖项)?

如何从多个项目访问公共资源文件

Puppet:如何在模块中共享公共资源/变量

通用公共资源集合

公共资源的 JWT 认证

不共享公共资源的线程是否有可能基于线程ID /名称进行通知?

使用 Kendo 调度程序资源分组时查找插槽的组

两个线程的公共资源-同步足够了吗?

Spring 库共享公共资源

春季启动网络和公共资源

静态属性中的公共资源

如何为多个模块创建公共资源文件夹?

如何将公共资源密集型对象传递给子类?

为什么Github页面网址在加载时发生更改,从而导致公共资源路径不正确?

在多模块Maven项目中指定公共资源

Gradle:多个Java项目的公共资源依赖关系

在Symfony2中使用另一个捆绑软件中的公共资源

使用New-AzureRmDeployment和链接的ARM模板创建资源组和资源时如何获取资源组名称?

您如何使用事件调度线程?

如何使用调度组同时开始加载?

如何在应用程序部署在多个实例负载平衡器后面的同步Java中的公共资源

新贡献者未显示在公共资源库中

正确的URI语法,用于引用DLL中的公共资源文件

流星铁路由器:在内部路线中加载公共资源

IBM Worklight控制台预览公共资源链接错误:找不到

使用调度组时,异步功能需要很长时间