title: Cocoa-Touch: performSelectorOnMainThread: weird behavior + crash
body: <p>I have a situation where I'm lazy loading images from the www.<br>
  It's a list of items, when one item is tapped, a detail view is pushed to a nav controller.</p>
  
  <p>In that detail view the item has an image, which first is a default image, and I want to start loading it's image from a URL.</p>
  
  <p>So what I do is create an object which once initialized detaches a new thread which in turn loads the content and afterwards notifies my view that the data is loaded:</p>
  
  <pre><code>// in MyLoader:
  - (MyLoader *)initWithUrl:(NSURL *)url requester:(id)requester {
      self.url = url;
      self.requester = requester; // both are nonatomic, retain properties
      [self performSelectorInBackground:@selector(loadIt) withObject:nil];
  }
  
  - (void)loadIt {
      NSAutoreleasePool *arp = [[NSAutoreleasePool alloc] init];
      NSData *data = [NSData dataWithContentsOfURL:url];
      [requester performSelectorOnMainThread:@selector(dataReady) withObject:data waitUntilDone:YES;
      [arp release];
  }
  
  // in MyRequester:
  - (void)somewhere {
      MyLoader *loader = [[[MyLoader] alloc] initWithUrl:someUrl requester:self] autorelease];
      // then I retain loader somewhere, it's more complicated but I have verified that it's properly retained.
  }
  </code></pre>
  
  <p>A few notes:</p>
  
  <ol>
  <li><p>First I thought there might be a problem with some of the variables. I put a breakpoint right before <code>performSelectorOnMainThread</code> and confirmed that <code>data</code> and <code>requester</code> were both OK.</p></li>
  <li><p>Then I thought it was caused by passing the NSData across the threads, so I changed <code>withObject:nil</code>. It still crashes.</p></li>
  <li><p>When I further investigated, the crash was very strange. I specified <code>waitUntilDone:YES</code>, I've placed a breakpoint in the <code>requester</code>'s <code>dataReady</code>. But the <code>performSelectorOnMainThread</code> call returns (it reaches the breakpoint after it) while not reaching the breakpoint inside <code>dataReady</code>. BTW, <code>- (void)dataReady:(NSData*)</code>'s body for now only contains <code>int x = 1;</code> (to place a breakpoint on). Also, I've tried setting <code>waitUntilDone:NO</code>, it still crashes.</p></li>
  <li><p>The selector isn't performed (the breakpoint is not reached), but the crash happens a short while after the call.</p></li>
  </ol>
  
  <p>Does anyone have any idea what's wrong?</p>
  
  <p>This is obvious, but just to be clear, if I just comment out the <code>[requester performSelectorOnMainThread...</code> part, it doesn't crash.</p>
  
  <p>Also, here's a stack trace, but it's not helpful at all.</p>
  
  <pre><code>#0  0x00a71004 in ___TERMINATING_DUE_TO_UNCAUGHT_EXCEPTION___ ()
  #1  0x93436e3b in objc_exception_throw ()
  #2  0x0028aca6 in __NSThreadPerformPerform ()
  #3  0x00a098e1 in CFRunLoopRunSpecific ()
  #4  0x00a08c48 in CFRunLoopRunInMode ()
  #5  0x0005a78d in GSEventRunModal ()
  #6  0x0005a852 in GSEventRun ()
  #7  0x0168a003 in UIApplicationMain ()
  #8  0x000028d4 in main (argc=1, argv=0xbffff100) at /Users/myName/Document/appName/main.m:14
  </code></pre>