Search code examples
iosobjective-cmultithreadingnsurlconnectiongrand-central-dispatch

NSURLConnection started in another thread. Delegate methods not called


I start a NSURLConnection in another thread:

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0),
        ^{
            NSURLConnection *connection = [NSURLConnection connectionWithRequest:[request preparedURLRequest] delegate:self];
            [connection start];
         });

But my delegate method is not called:

- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData*)data;

When run on the main thread everything is fine. How can I run connection on another thread and get the delegate methods called at the same thread too?


Solution

  • GCD creates, destroys, reuses threads implicitly and there is a chance that the thread you call start from will stop existing immediately afterwards. This may result in the delegate not receiving any callbacks.

    If you would like to receive callback in background thread, you can use setDelegateQueue or sendAsynchronousRequest:queue:completionHandler: method:

    NSURLConnection* connection = [[NSURLConnection alloc] initWithRequest:request
                                                              delegate:self
                                                      startImmediately:NO];
    [connection setDelegateQueue:[[NSOperationQueue alloc] init]];
    [connection start];
    

    The easiest way to start NSURLConnection in the background thread via GCD is:

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0),
                   ^{
                       NSURLResponse* response = nil;
                       NSError* error = nil;
                       [NSURLConnection sendSynchronousRequest:request] returningResponse:&response error:&error];
                       NSLog(@"%@", response);
                   });