【问题标题】:How to make a common resource thread safe when using dispatch group?使用调度组时如何使公共资源线程安全?
【发布时间】:2020-07-15 03:42:52
【问题描述】:

我有一个 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。但我不确定这是否是正确的方法。

【问题讨论】:

    标签: ios swift grand-central-dispatch dispatchgroup dispatchsemaphore


    【解决方案1】:

    你问:

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

    在您的代码 sn-p 中没有线程安全问题,因为 Alamofire 在主线程上调用其完成处理程序。他们这样做是为了帮助减轻多线程问题。在这种情况下,不需要任何 DispatchQueue.main.async。作为 Alamofire documentation says:

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

    所以除非你做了一些不寻常的事情(例如用一些并发的DispatchQueue 覆盖默认的.main 队列),Alamofire 将在主线程上运行其完成处理程序,从而减轻线程安全问题。

    如果您使用的其他 API 没有在主线程上调用其完成处理程序(例如,URLSession.shared 在后台队列上调用其完成处理程序),那么可能会有问题,但 Alamofire 不会。 (甚至URLSession 使用串行后台队列,因此使用您的模式不会出现问题,您正在更新局部变量。)

    最重要的是,只要您不同时从多个线程更改/访问变量,线程安全问题就会大大减轻。

    【讨论】:

      猜你喜欢
      • 2012-10-22
      • 1970-01-01
      • 1970-01-01
      • 2021-05-13
      • 1970-01-01
      • 1970-01-01
      • 2012-11-21
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多