15

I watched this years WWDC GCD talk lately and I think there is a code snippet something is wrong with. It is about making a property thread-safe using DispatchQueues.

class MyObject {
    private var internalState: Int
    private let internalQueue: DispatchQueue // Serial or Concurrent?

    var state: Int {
        get {
            return internalQueue.sync { internalState }
        }

        set (newState) {
            internalQueue.sync { internalState = newState }
        }
    }
}

They use a DispatchQueue to lock a property. But i think this snippet is not valid, because the internalQueue could be concurrent. So if we call the setter from two different DispatchQueues/Threads if that internal queue is not serial, it could also lead to threading problems right? Because in my understanding sync just holds the invoking thread and continues if the task is complete. What do you think about this snippet? Am I wrong?

1
  • 4
    Yes, you would define internalQueue as a serial dispatch queue. Commented Jul 14, 2016 at 11:49

2 Answers 2

24

I'd like just to show another approach that makes you able to read concurrently, but block everything while writing by using a dispatch barrier.

class MyObject {
private var internalState: Int
private let internalQueue = DispatchQueue(label: "reader-writer", attributes: .concurrent)

var state: Int {
    get {
        return internalQueue.sync { internalState }
    }

    set (newState) {
        internalQueue.async(flags: .barrier) { internalState = newState }
    }
  }
}

With that approach, reads can occur concurrently on the queue, but writes are executed exclusively, due to the barrier.

This is just a Swift 3 conversion of an approach explained in the book Effective Objective C 2.0, written by Matt Galloway.

Sign up to request clarification or add additional context in comments.

2 Comments

Nice. Could also use a private concurrent queue here.
This question provides more context on the .barrier option.
13

But i think this snippet is not valid, because the internalQueue could be concurrent

But it isn't concurrent. Dispatch queues that you create are serial by default. That is the point of the technique (and the example).

2 Comments

You might want to watch WWDC videos on GCD from earlier years. They are clearer on this point.
Thanks Matt,I didn't know that.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.