title: Intangible Order of Execution (dispatch_semaphore_t, dispatch_group_async) and the Use of Them in Combination with Different Dispatch Queue Types
body: <p>I just took some time in the evening to play around with GCD, especially with <code>dispatch_semaphore_t</code> because I never used it. Never had the need to.</p>
  <p>So I wrote the following as a test:</p>
  <pre><code>- (void)viewDidLoad
  {
          UIView *firstView = [[UIView alloc] initWithFrame:(CGRect){{0, 0}, self.view.frame.size.width/4, self.view.frame.size.width/5}];
          firstView.backgroundColor = [UIColor purpleColor];
          [self.view addSubview:firstView];
  
  
          dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^
          {
              for (long i = 0; i &lt; 1000; i++)
              {
                  sleep(5);
                  dispatch_async(dispatch_get_main_queue(), ^
                  {
                      firstView.layer.opacity = ((i%2) ? 0: 1);
                  });
              }
          });
  
          dispatch_queue_t queue1 = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
          dispatch_group_t group1 = dispatch_group_create();
  
          dispatch_group_async(group1, queue1, ^
          {
               sleep(3);
               NSLog(@&quot;dispatch group 1&quot;);
          });
          
          dispatch_group_notify(group1, queue1, ^
          {
              NSLog(@&quot;dispatch notify 1&quot;);
          });
  
          dispatch_async(myQueue, ^
          {
              for(int z = 0; z &lt; 10; z++)
              {
                  NSLog(@&quot;%i&quot;, z);
                  sleep(1);
              }
              dispatch_semaphore_signal(mySemaphore);
         });
  
         dispatch_semaphore_wait(mySemaphore, DISPATCH_TIME_FOREVER);
         NSLog(@&quot;Loop is Done&quot;);
  }
  </code></pre>
  <p>If I ran the above, the output would be:</p>
  <blockquote>
  <p>0</p>
  <p>1</p>
  <p>2</p>
  <p>dispatch group 1</p>
  <p>dispatch notify 1</p>
  <p>3</p>
  <p>4</p>
  <p>5</p>
  <p>6</p>
  <p>7</p>
  <p>8</p>
  <p>9</p>
  <p>Loop is Done</p>
  </blockquote>
  <p>After the above, <code>firstView</code> appears on the screen (before <code>semaphore</code> the whole screen was black) and finally this gets executed:</p>
  <pre><code>dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^
  {
      for (long i = 0; i &lt; 1000; i++)
      {
          sleep(5);
          dispatch_async(dispatch_get_main_queue(), ^
          {
              firstView.layer.opacity = ((i%2) ? 0: 1);
          });
      }
  });
  </code></pre>
  <p>Which <em>only</em> alternates the <code>opacity</code> as the loop runs after <code>semaphore</code> is done.</p>
  <hr />
  <p><em><strong>1.)</strong></em></p>
  <p>So, it seems that I have to wait until <code>dispatch_semaphore</code> finish to do its work before any UI thing takes place.</p>
  <p><strong>BUT</strong>:</p>
  <p>It seems like <code>dispatch_group_t</code> runs concurrently with <code>dispatch_semaphore</code> as shown from the output above (i.e., 1, 2, 3, ....).</p>
  <p>???</p>
  <hr />
  <p><em><strong>2.)</strong></em></p>
  <p>And if I change the <code>for loop</code> in the above to using: <code>dispatch_async(dispatch_get_main_queue(), ^</code></p>
  <p>instead of:</p>
  <p><code>dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^</code>,</p>
  <p>nothing gets shown on the screen even after <code>semaphore</code> is done.</p>
  <p>How so???</p>
  <hr />
  <p><em><strong>3.)</strong></em></p>
  <p>Furthermore if I change <code>semaphore</code> to the following as opposed to using a global queue like in the above:</p>
  <pre><code>dispatch_async(dispatch_get_main_queue(), ^
  {
      for(int z = 0; z &lt; 10; z++)
      {
          NSLog(@&quot;%i&quot;, z);
          sleep(1);
      }
      dispatch_semaphore_signal(mySemaphore);
  });
  </code></pre>
  <p>Only <code>dispatch_group</code> takes place; nothing else take places / get executed, not the <code>for loop</code> in the above, including UI. Nothing.</p>
  <hr />
  <p><em><strong>4.)</strong></em></p>
  <p>So besides what I pointed out in the above, what can I do, in order to make <code>semaphore</code> not blocking my UI and my other process and just let my UI and the other processes do their thing?</p>
  <p>And as mentioned above, why changing the type of queue for <code>semaphore</code> from global to main would cause nothing to be shown on screen and even the loop would not execute except <code>dispatch_group</code>?</p>
  <hr />
  <p><em><strong>5.)</strong></em></p>
  <p>If I change <code>semaphore</code> to:</p>
  <pre><code>dispatch_semaphore_t mySemaphore = dispatch_semaphore_create(1); 
  
  //1 instead of 0 (zero)
  </code></pre>
  <p>Everything (i.e., both for loop and UI) runs immediately and <code>NSLog(@&quot;Loop is Done&quot;);</code> is displayed also immediately, which tells me that semaphore didn't wait here:</p>
  <pre><code>dispatch_semaphore_wait(mySemaphore, DISPATCH_TIME_FOREVER);
  NSLog(@&quot;Loop is Done&quot;);
  </code></pre>
  <p>???</p>
  <hr />
  <p>I spent the whole evening trying to figure this out, but to no avail.
  I hope someone with great GCD knowledge can enlighten me on this.</p>