我有一个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] 删除。
我来说两句