简体   繁体   中英

dispatch_async(dispatch_get_main_queue() not firing after NSMutableURLRequest with timeoutInterval

I am using the following (simplified) GCD call in my app:

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{

    NSString *query = "/api/something";
    NSString *parameters = "a=1234&b=5678";   

    _myDict = (NSMutableDictionary*)[NetworkUtility postDataToServer:query withParameters:parameters];  


        // Done with API Call
        dispatch_async(dispatch_get_main_queue(), ^{

            // Do something

        });

});

When the call is made to NetworkUtility , a NSURL Connection is called is made to:

 NSData *postData = [parameters dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES];
 NSString *postLength = [NSString stringWithFormat:@"%lu",(unsigned long)[postData length]];

 NSString *urlString = [NSString stringWithFormat:@"https://myapp.com%@", query];

 NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:urlString] cachePolicy:NSURLRequestReloadIgnoringLocalAndRemoteCacheData timeoutInterval:7.0];

 [request setHTTPMethod:@"POST"];
 [request setValue:postLength forHTTPHeaderField:@"Content-Length"];
 [request setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content-Type"];
 [request setHTTPBody:postData];

 NSData *response = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];

 return response;

The result is that if the network receives a response, the dispatch_async(dispatch_get_main_queue() block fires as expected, but if the network call times out and the _recommendationDictionary is nil, the dispatch_async(dispatch_get_main_queue() never fires.

Why does dispatch_async(dispatch_get_main_queue() not fire immediately, if the NetworkUtility is returning a value?

The block is enqueued on the main queue. The main queue is a serial queue, and it will execute the enqueued blocks in order.

If you use a CFRunLoop on the main thread, then the main dispatch queue is drained in that run loop, so if the run loop is occupied with other activity, it will also cause a delay in executing those blocks.

If you don't actually need to do UI or other activities that are serialized on the main thread, you're probably best off not using the main queue.

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