title: Block gets released whilst in NSDictionary (ARC)
body: <p>I'm trying to retain a reference to a Block that's been passed in to my class by a method, to call at a later time. I'm having trouble, however, maintaining a reference to it.</p>
  
  <p>The obvious way, I thought, was to add it to an ivar collection, all of which are supposed to maintain strong references to their contents. But when I try to pull it back out, it's nil.</p>
  
  <p>The code is pretty simple:</p>
  
  <pre><code>typedef void (^DataControllerCallback)(id rslt);
  
  @interface DataController : NSObject {
      NSMutableArray* queue;
  }
  - (void) addBlock:(DataControllerCallback)callback;
  - (void) functionToBeCalledLater;
  @end
  
  @implementation DataController
  
  - (id) init {
      self = [super init];
      if (self != nil) {        
          queue = [NSMutableArray new];
      }
      return self;
  }
  
  - (void) addBlock:(DataControllerCallback)callback {
      NSDictionary* toAdd = [NSDictionary dictionaryWithObjectsAndKeys:
          [callback copy], @"callback",
          @"some other data", @"data", nil];
      [queue addObject:toAdd];
  }
  
  - (void) functionToBeCalledLater {
      NSDictionary* dict = [queue lastObject];
      NSLog(@"%@", [dict objectForKey:@"data"]; //works
      DataControllerCallback callback = [dict objectForKey:@"callback"]; //this is nil
      callback(@"an arguemnt"); //EXC_BAD_ACCESS
  }
  </code></pre>
  
  <p>What's happening?</p>
  
  <hr>
  
  <p>Update: I've tried it with <code>[callback copy]</code> and just <code>callback</code> inserting into the dictionary, neither works.</p>
  
  <hr>
  
  <p>Update 2: If I just stick my block into an NSMutableSet, as long as I call <code>copy</code>, I'm fine. It works great. But if it's in an NSDictionary, it doesn't.</p>
  
  <p>I've actually tested it by putting a breakpoint right after the NSDict is created and the callback never gets inserted. The description reads clearly "1 key-value pair", not two.</p>
  
  <p>I'm currently getting around this with a specialised class that just acts as a container. The <code>callback</code> property is declared as <code>strong</code>; I don't even need to use <code>copy</code>.</p>
  
  <p>The question still stands, though: why is this happening? Why won't an NSDictionary store a Block? Does it have something to do with the fact that I'm targeting iOS 4.3 and thus ARC must be built in as a static library?</p>
  
  <hr>
  
  <p>Update 3: Ladies and gentleman: I am an idiot.</p>
  
  <p>The code I presented here was obviously a simplified version of the actual code; most particularly, it was leaving some key/value pairs out of the dictionary.</p>
  
  <p>If you're storing a <strong>value</strong> in an NSDictionary using <code>[NSDictionary dictionaryWithObjectsAndKeys:]</code>, you had better be <em>damn</em> sure one of those values isn't <code>nil</code>.</p>
  
  <p>One of them was.</p>
  
  <p>ICYMI, it was causing an early termination of the argument list. I had a userInfo-type argument being passed into one of the "add to queue" methods, and you could, of course, pass in "nil". Then when I constructed the dictionary, chucking in that argument caused the constructor to think I had terminated the argument list. <code>@"callback"</code> was the last value in the dictionary constructor and it was never being stored.</p>