NSURLSessionTask completionTask never get call in main queue using GCD

2.2k views Asked by At

I am using iOS 7 NSURLSession to do some simple GET to a RESTful service. This is what i did:

NSURLSessionConfiguration *sessionConfig = [NSURLSessionConfiguration ephemeralSessionConfiguration];
_session = [NSURLSession sessionWithConfiguration:sessionConfig delegate:nil delegateQueue:[NSOperationQueue mainQueue]]; 

// create your url at this line
NSURLRequest *request = [NSURLRequest requestWithURL:url];

NSURLSessionTask *task = [self.session dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
   // do something with the result 
}]; 
[task resume];

All of the above code works fine. The completionHandler should get called in the main queue.

However, if i use this in GCD, like so:

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
   // do some heavylifting in the background

   for (int i = 0; i < 10000000; i++) ;

   dispatch_async(dispatch_get_main_queue(), ^{
       // do the exact same thing as the above NSURLSession call
       NSURLSessionConfiguration *sessionConfig = [NSURLSessionConfiguration ephemeralSessionConfiguration];
       _session = [NSURLSession sessionWithConfiguration:sessionConfig delegate:nil delegateQueue:[NSOperationQueue mainQueue]]; 

       // create your url at this line
       NSURLRequest *request = [NSURLRequest requestWithURL:url];

       NSURLSessionTask *task = [self.session dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
          // do something with the result 
       }]; 
       [task resume];
   });
});

Now, i thought i run that code within the dispatch_get_main_queue(), which should be the same as [NSOperationQueue mainQueue] as specified in the session's delegateQueue?? Tt should be effectively running in the main thread just like the 1st set of code. However, what i discovered is that the completionHandler is never called. And if i remove the GCD code, it works again.

Has anyone tried to do this before? Should this work? or I have misunderstanding where the work had dispatched to which queue?

1

There are 1 answers

0
Clay Bridges On

AFAIK, all NSURLSession callbacks happen on the queue specified by the readonly NSURLSession. delegateQueue property (docs), which can be specified on initialization.