title: Block in sync method on background queue is executed on main thread
body: <p>Just started to learning about GCD and I am running into trouble because my code is still ran on the main thread while I created a background queue. This is my code:</p>
  
  <pre><code>import UIKit
  
  class ViewController: UIViewController {
  
      let queue = DispatchQueue(label: "internalqueue", qos: .background)
  
      override func viewDidLoad() {
          super.viewDidLoad()
  
          dispatchFun {
              assert(Thread.isMainThread)
  
              let x = UIView()
          }
      }
  
      func dispatchFun(handler: @escaping (() -&gt; ())) {
          queue.sync {
              handler()
          }
      }
  }
  </code></pre>
  
  <p>Surprising enough (for me), is that this code doesn't throw any error! I would expect the assertion would fail. I would expect the code is not ran on the main thread. In the debugger I see that when constructing the <code>x</code> instance, that I am in my queue on thread 1 (by seeing the label). Strange, because normally I see the main thread label on thread 1. Is my queue scheduled on the main thread (thread 1)?</p>
  
  <p><strong>When I change <code>sync</code> for <code>async</code>, the assertion fails</strong>. This is what I would expect to happen with <code>sync</code> aswell. Below is an attached image of the threads when the assertion failed. <strong>I would expect to see the exact same debug information when I use <code>sync</code> instead of <code>async</code>.</strong></p>
  
  <p><a href="https://i.stack.imgur.com/jNJUE.png" rel="noreferrer"><img src="https://i.stack.imgur.com/jNJUE.png" alt="enter image description here"></a></p>
  
  <p>When reading the <code>sync</code> description in the Swift source, I read the following:</p>
  
  <pre><code>/// As an optimization, `sync(execute:)` invokes the work item on the thread which
  /// submitted it, except when the queue is the main queue or
  /// a queue targetting it.
  </code></pre>
  
  <p>Again: <strong>except when the queue is the main queue</strong></p>
  
  <p>Why does the <code>sync</code> method on a background dispatch queue cases the code to run on the main thread, but <code>async</code> doesn't? I can clearly read that the sync method on a queue shouldn't be ran on the main thread, but why does my code ignore that scenario? </p>