Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Resolving Data Race in iOS Swift

I have NetworkProvider which will make api call continuously and also once I received the data i will update the userid. At the same time I will access the userid from other functions.

This is data race condition, can someone help to remove the condition.

`

class NetworkProvider  {
   public var userID: String

   func observeStateChange() {

        FIRAuth.auth()?.addStateDidChangeListener({ (auth, authenticatedUser) in
          if let user = authenticatedUser {
              userID = user.uid
          }
       }
    }

   func currentUserID() -> String {
        return self.userID
  }
}`
like image 474
venky Avatar asked Sep 25 '17 21:09

venky


People also ask

How do I fix data race?

As different threads use the same value of i, the data-races occur. One way to fix the problem is to pass i to work() by value. This ensures that each thread has its own private copy of i with a unique value.

How can we avoid data races?

A common mechanism to avoid data races is to force a mutual exclusion. In the previous example, you can enforce sequence 1 by: Locking a mutex before Task1: sharedVar1 = 11; Unlocking the mutex after Task1: do_sth_wth_shared_resources1();

What is data race in Swift?

A data race occurs when 2 or more threads trying to access (read/write) the same memory location asynchronously at the same time. In the context of Swift, it usually happens when we try to modify an object's state using a dispatch queue.

What is the difference between data race and race condition?

A race condition occurs when the timing or order of events affects the correctness of a piece of code. A data race occurs when one thread accesses a mutable object while another thread is writing to it.


1 Answers

Use DispatchQueue can avoid data race:

class NetworkProvider  {
    let isolationQueue = DispatchQueue(label: "com.your.domain.xxx", attributes: .concurrent)
    private var _userID: String
    public var userID: String {
        set { isolationQueue.async(flags: .barrier) { self._userID = newValue } }        
        get { return isolationQueue.sync { _userID } }
    }

    func observeStateChange() {

        FIRAuth.auth()?.addStateDidChangeListener({ (auth, authenticatedUser) in
            if let user = authenticatedUser {
                userID = user.uid
            }
        }
    }

    func currentUserID() -> String {
        return self.userID
    }
}
like image 96
DàChún Avatar answered Nov 15 '22 08:11

DàChún