title: Grand Central Dispatch and functions
body: <p>I've been looking at <a href="https://stackoverflow.com/questions/11728098/ios-objective-c-equivalent-of-androids-asynctask">this question</a> to try to solve the problem I have <a href="https://stackoverflow.com/questions/20473096/is-it-possible-to-update-something-in-the-ui-while-performing-synchronous-calls">here</a>.  The tl;dr is I want to use GCD to let me show a "Waiting" screen while I preform some tasks, then hide the screen when it's done.  Right now, I have </p>
  
  <pre><code>- (void) doStuff
  {
      // Show wait on start
      [self.waitScreen setHidden:NO];
  
      dispatch_queue_t queue = dispatch_queue_create("com.myDomain.myApp",null);
      dispatch_async(queue, ^{
          dispatch_async(dispatch_get_main_queue(), ^{
              // Double nesting the dispatches seems to allow me to do UI changes as part of 'Code to execute' below.
              // If I do not double nest like this, the UI still freezes while it executes
              dispatch_queue_t queue2 = dispatch_queue_create("com.myDomain.myApp",null);
              dispatch_async(queue2, ^{
                  dispatch_async(dispatch_get_main_queue(), ^{
  
                      // Code to execute
                      {
                          //... Do my time consuming stuff here ...
                          // For testing purposes, I'm using
                          int i = 0;
                          while (i &lt; 1000000000)
                          {
                              i++;
                          }
                      }
  
                      // Hide Wait Screen on End
                      [self.waitScreen setHidden:YES];
                  });
              });
          });
      });
  }
  </code></pre>
  
  <p>And this works just how I want.  I'm calling <code>[self doStuff]</code> like so </p>
  
  <pre><code>- (IBAction) buttonTouchUpInside:(id)sender
  {
      [self doStuff];
  }
  
  - (void) doStuff
  {
      // ... code from first code block here ...
  }
  </code></pre>
  
  <p>Everything to this point works perfectly.  Now, I've discovered I will need to use this in a function call.  So I need something like:</p>
  
  <pre><code>- (IBAction) buttonTouchUpInside:(id)sender
  {
      NSMutableString *string= [self doStuff];
  
      // ... use 'string' to do other stuff ...
      // For testing, I'm using
      self.label.text = string;
  }
  
  - (NSMutableString *) doStuff
  {
      // ... code from first code block here ...
  }
  </code></pre>
  
  <p>How do I need to change the syntax to be able to pass variables around with <code>dispatch_async</code>?  </p>
  
  <hr>
  
  <p>I looked at the <a href="https://developer.apple.com/library/ios/documentation/cocoa/conceptual/ProgrammingWithObjectiveC/WorkingwithBlocks/WorkingwithBlocks.html" rel="nofollow noreferrer">Apple Docs</a> and tried </p>
  
  <pre><code>- (IBAction) buttonTouchUpInside:(id)sender
  {
      NSMutableString *string= [self doStuff];
  
      // ... use 'string' to do other stuff - shows 'nil' when I put breakpoints here ...
      // For testing, I'm using
      self.label.text = string;
  }
  
  - (NSMutableString *) doStuff
  {
      __block NSMutableString *string = [[NSMutableString alloc] initWithString:@"Initing"];
  
      // Show wait on start
      [self.waitScreen setHidden:NO];
  
      dispatch_queue_t queue = dispatch_queue_create("com.myDomain.myApp",null);
      dispatch_async(queue, ^{
          dispatch_async(dispatch_get_main_queue(), ^{
              dispatch_queue_t queue = dispatch_queue_create("com.myDomain.myApp",null);
              dispatch_async(queue, ^{
                  dispatch_async(dispatch_get_main_queue(), ^{
  
                      // Code to execute
                      {
                          int i = 0;
                          while (i &lt; 1000000000)
                          {
                              i++;
                          }
  
                          [string setString:@"Hello World"];
                      }
  
                      // Hide Wait Screen on End
                      [self.waitScreen setHidden:YES];
                  });
              });
          });
      });
  
      return string;
  }
  </code></pre>
  
  <p>But when I run this, <code>label</code> just shows <code>Initing</code>.  I need it to show <code>Hello World</code>.  None of the changes I make in the block are being passed through.  </p>
  
  <p>After looking at some other questions, this seems to be referred to as a "race condition".  As I understand it, once it hits the <code>dispatch_async</code>, the code in the block starts running on a new thread, but the code outside of the block continues to run at the same time on the old thread.  So it looks like the thread outside the block is getting to <code>self.label.text = string</code> before the thread running the block can get to <code>[string setString:@"Hello World"];</code>.  How can I make the <code>self.label.text = string</code> line wait until <code>[string setString:@"Hello World"];</code> finishes?</p>