Everyone knows NSOperation is easily the best way to automatically gain powerful multi-threading on iOS/Mac platforms. However, recently for one of my apps, I faced a issue where, the NSURLConnection’s initWithRequest method doesn’t automatically start even if you forcefully send the “start” message.

For example the below code works perfectly on iPhone OS 3.1 and below but fails on iOS 4.

- (void)start
{
[self willChangeValueForKey:@"isExecuting"];
_isExecuting = YES;
[self didChangeValueForKey:@"isExecuting"];

NSURLRequest * request = [NSURLRequest requestWithURL:_url];
_connection = [[NSURLConnection alloc] initWithRequest:request
delegate:self];
}

Seems like Apple has made a change where in if the NSURLConnection’s initWithRequest method is called from a thread that’s not the main thread, it doesn’t start downloading the URL contents immediately. The bug fix for this issue is fortunately simple.


- (void)start
{
[self willChangeValueForKey:@"isExecuting"];
_isExecuting = YES;
[self didChangeValueForKey:@"isExecuting"];

NSURLRequest * request = [NSURLRequest requestWithURL:_url];
_connection = [[NSURLConnection alloc] initWithRequest:request
delegate:self];


//iOS 4 bug fix
if (![NSThread isMainThread])
{
[self performSelectorOnMainThread:@selector(start)
withObject:nil waitUntilDone:NO];
return;
}

}

Hope this post solves your problem.


Mugunth

Follow me on Twitter

If you enjoyed this post, make sure you subscribe to my RSS feed!

Related posts:

  1. Easy Debugging with NSMutableURLRequest This post is a sequel to one of my previous...

  • Ankit Gupta

    Does this mean that all the nsurlconnection delegates will also be serviced on the main thread?

  • Shashi

    Will the delegate be called in main thread or background nsoperation thread?

  • Remy Demarest

    Why do you put the fix at the end of the method ? It should be at the beginning of the method or else you’re leaking the memory for the first connection and its hanging there doing nothing and retaining the delegate…

  • Tal

    Shouldn’t it be:

    [_connection performSelectorOnMainThread:@selector(start)
    withObject:nil waitUntilDone:NO];

    ?

  • Mark J

    You have just saved my shit.