title: Why does GCD dispatch_async on main queue causes a deadlock from background queue?
body: <p>I am creating a serial background queue like this:</p>
  
  <pre><code>@property (nonatomic, strong) dispatch_queue_t assetCreationQueue;
  
  // in init...
  _assetCreationQueue = dispatch_queue_create("com.mycompany.assetCreationQueue", DISPATCH_QUEUE_SERIAL);
  </code></pre>
  
  <p>Then I enumerate ALAsset objects in the background like this:</p>
  
  <pre><code>[group enumerateAssetsUsingBlock:^(ALAsset *asset, NSUInteger index, BOOL *stop){
      if (asset){
          dispatch_async(weakSelf.assetCreationQueue, ^{
              ALAssetRepresentation *assetRepresentation = [asset defaultRepresentation];
              NSURL *url = [assetRepresentation url];
              if (url) {
                  AVURLAsset *avAsset = [[AVURLAsset alloc] initWithURL:url options:nil];
  
                  // This NSLog fires! avAsset exists.
                  NSLog(@"AVURLAsset %@", avAsset);
  
                  dispatch_async(dispatch_get_main_queue(), ^{
                      // This NSLog NEVER fires.
                      // Also tried dispatch_sync.
                      NSLog(@"add to assets array on main queue");
                      [weakSelf.assets insertObject:avAsset atIndex:0];
                  });
              }
          });
      }
  }];
  </code></pre>
  
  <p>The assets array property is defined as:</p>
  
  <pre><code>@property (nonatomic, strong) NSMutableArray *assets;
  </code></pre>
  
  <p>When I try <code>dispatch_sync(dispatch_get_main_queue(), ^{</code> I only get ONE <code>NSLog(@"AVURLAsset %@", avAsset);</code> in the console and it indicates that <code>dispatch_sync</code> is causing a deadlock.</p>
  
  <p>But how can I find out why? I don't see where. The assetCreationQueue is a background queue and I have to operate on the array only on the main queue.</p>
  
  <p><strong>EDIT:</strong>
  Here is a much more simplified test which also fails:</p>
  
  <pre><code>[group enumerateAssetsUsingBlock:^(ALAsset *asset, NSUInteger index, BOOL *stop){
      if (asset){
          dispatch_async(weakSelf.assetCreationQueue, ^{
              if ([NSThread isMainThread]) {
                  NSLog(@"already main thread"); // gets called often!!
              } else {
                  dispatch_async(dispatch_get_main_queue(), ^{
                      NSLog(@"dispatch async on main queue"); // never gets called!!
                  });
              }
          });
       }
  }];
  </code></pre>
  
  <p>So what I don't understand is: Why am I already on the main thread even though I call <code>dispatch_async(weakSelf.assetCreationQueue</code>. It can only lead to evil conclusion: The queue I create is NOT a background queue:</p>
  
  <pre><code>_assetCreationQueue = dispatch_queue_create("com.mycompany.assetCreationQueue", DISPATCH_QUEUE_SERIAL);
  </code></pre>
  
  <p>Why?</p>