简体   繁体   中英

Under what circumstances does dispatch_async(dispatch_get_main_queue(), ^ … do nothing

In the completion routine for

[NSURLConnection sendAsynchronousRequest:request
                                   queue:queue
                       completionHandler:^(NSURLResponse *response, NSData *data, NSError *error)

I am calling

dispatch_async(dispatch_get_main_queue(), ^
{
  NSLog(@"CALLING SUCCESS");
});

I have two test applications, in one this works correctly, and the other it does not. What happens is the the log statement does not execute. The queue was created with

queue = [[NSOperationQueue alloc] init];

Driving me nuts, it simply refuses to execute at all. I called this during the application launch in both cases. I tried delaying the call for 5 seconds. No matter what I do it will not execute the block in one app but does in the other. If I had some clue on under what circumstances dispatch_async(dispatch_get_main_queue()... could fail I might be able to discern the difference.

Note that in the actual code I am calling a block which I want to execute on the main thread. I reduced the test case to just calling NSLog.

UPDATE: The difference is that this code doesn't work on the iOS 5.1 simulator, but does work on 6.0 or 6.1. Why?

UPDATE 2: OK, if I use a default NSURLConnection it does work, but if I use

self.connection = [[NSURLConnection alloc]initWithRequest:request delegate:self startImmediately:NO];
[self.connection setDelegateQueue:queue];
[self.connection start];

It doesn't work in iOS 5.1. Beginning to think this might be a bug in 5.1 with setDelegateQueue.

OK, the real problem is this. If you use NSURLConnection's class method

+ (void)sendAsynchronousRequest:(NSURLRequest *)request
                      queue:(NSOperationQueue *)queue
          completionHandler:(void (^)(NSURLResponse *, NSData *, NSError *))handler

under iOS 5 or 6 it everything works fine.

If instead (like I did) you implement your own connection handler, ie roll your own equivalent to the class method (in my case to avoid caching) by implementing NSURLConnectionDelegate and NSURLConnectionDataDelegate, and calling

self.connection = [[NSURLConnection alloc]initWithRequest:request delegate:self startImmediately:NO];
[self.connection setDelegateQueue:queue];
[self.connection start];

then the dispatch_async won't work under iOS 5.X but will work under iOS 6.X. I think Apple fixed a bug.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM