title: GCD async block & EXC_BAD_ACCESS
body: <p>This crash is fairly rare, but it has happened often enough to convince me I'm doing it wrong.</p>
  
  <p>It's an API call performed using both main-thread async dispatch and barrier dispatch on a custom concurrent queue (the barrier is used because we're modifying data that is read elsewhere, via non-barrier calls to the same queue).</p>
  
  <p>The objective is to make the HTTP request asynchronously, and then fire off a dispatch_barrier_async to handle the resulting data.</p>
  
  <p>The crash is happening when the dispatch_barrier_async call is copying the variables that are used in the passed block. I suppose that the variable has been deallocated before it gets used in the block, but given how I'm declaring it (as a __block variable) I don't see how that could be happening (unless the problem is with the other side of the assignment operator...). </p>
  
  <p>Here's the stack trace:</p>
  
  <pre><code>
  #0  0x00004f44 in __Block_byref_object_copy_ at /blah/ABEvent.m:156
  #1  0x0000582d in __copy_helper_block_ at /blah/ABEvent.m:191
  #2  0x02cf3be2 in _Block_call_copy_helper ()
  #3  0x02cf3681 in _Block_copy_internal ()
  #4  0x02c25526 in _dispatch_Block_copy ()
  #5  0x02c26802 in dispatch_barrier_async ()
  #6  0x00004e71 in __18+[ABEvent fetch]_block_invoke at /blah/ABEvent.m:159
  #7  0x00056e77 in __88-[ABClient get:parameters:success:failure:]_block_invoke_2 at /blah/ABClient.m:375
  #8  0x02c2553f in _dispatch_call_block_and_release ()
  #9  0x02c37014 in _dispatch_client_callout ()
  #10 0x02c277d5 in _dispatch_main_queue_callback_4CF ()
  #11 0x02facaf5 in __CFRunLoopRun ()
  #12 0x02fabf44 in CFRunLoopRunSpecific ()
  #13 0x02fabe1b in CFRunLoopRunInMode ()
  #14 0x02f517e3 in GSEventRunModal ()
  #15 0x02f51668 in GSEventRun ()
  #16 0x01ef1ffc in UIApplicationMain ()
  #17 0x0005164d in main at /blah/main.m:3
  #18 0x00002db5 in start ()
  </code></pre>
  
  <p>And the code:</p>
  
  <pre><code>
  + (void)fetch {
      ABBlock _success = ^(ABMessage *m) {
  
          __block NSMutableArray *fetched = [NSMutableArray arrayWithArray:m.params[@"live"]];
          [fetched addObjectsFromArray:m.params[@"soon"]]; // EXC_BAD_ACCESS (top of stack)
  
          dispatch_barrier_async([ABEvent eventQueue], ^{  // CRASHED IN BLOCK INVOKE (stack line 6)
              NSMutableArray *events = [NSMutableArray array];
  
              for (NSDictionary *d in fetched) {
                  [events addObject:[ABEvent eventWithDictionary:d]];
              }
  
              AppDelegate *appDelegate = (AppDelegate *)[UIApplication sharedApplication].delegate;
              appDelegate.events = events;
  
              events = nil;
          });
      };
  
      [[ABClient sharedInstance] events:_success failure:nil];
  }
  
  </code></pre>
  
  <p>Upstream:</p>
  
  <pre><code>
  
  -(void)events:(ABBlock)success failure:(ABBlock)failure {
      NSString *params = [NSString stringWithFormat:@"%@",[ABUser loggedInUser]? [ABUser loggedInUser].name : @"no"];
      NSDictionary *dict = @{@"loggedIn": params};
  
      [self get:@"events/live.json" parameters:dict success:success failure:failure];
  }
  
  - (void)get:(NSString *)path
   parameters:(NSDictionary *)parameters
      success:(ABBlock)success
      failure:(ABBlock)failure
  
      __block ABBlock blockSuccess = success;
      __block ABBlock blockFailure = failure;
      NSString *blockPath = path;
      NSDictionary *blockParameters = parameters;
  
      AFHTTPSuccessBlock _success = ^(AFHTTPRequestOperation *request, id response) {
          if (blockSuccess) {
              ABMessage *msg = [ABMessage messageWithObject:response];
              dispatch_async(dispatch_get_main_queue(), ^(void) {
                  blockSuccess(msg);
              });
          }
  
      };
  }
  
  Elsewhere:
  
  typedef void (^ABBlock) (ABMessage *);
  
  </code></pre>
  
  <p>Is there anything obviously wrong with how the variables are being used by the barrier_async block? I'm wondering if I should be copying the message (*m) being passed in as an argument.</p>