Why a sync block of code always call on main thread?

Viewed 1040

I did the simple test with DispatchQueue:

DispatchQueue.global(qos: .background).sync {
  if Thread.isMainThread {
    print("Main thread")
  }
}

It printed out:

Main thread

Why does this code execute on the main thread? It should be performed on a background thread (it was added to a background queue), right?

2 Answers

Because it doesn't actually have to. You're blocking the main thread by using sync. iOS is choosing to just execute it on the main thread instead of bothering to switch to a background thread (of a background queue) as it doesn't really matter due to main thread being blocked anyways.

Apple's docs (and quickhelp) on the sync function include the line:

As an optimization, this function invokes the block on the current thread when possible.

The problem is you asked the wrong question. Don't confuse queues and threads. Work with queues and let them rejigger the threads as needed. That is exactly why we have queues! You have no business worrying what thread you're on. All you need to know is that you're on the right queue, which you can find out like this:

let q = DispatchQueue.global(qos: .background)
q.sync {
    dispatchPrecondition(condition: .onQueue(q))
    print("it's okay! we're on the right queue") // yep
}
Related