dispatch_async(dispatch_get_main_queue()在使用timeoutInterval的NSMutableURLRequest之后没有触发

时间:2015-11-24 20:46:46

标签: ios grand-central-dispatch nsmutableurlrequest

我在我的应用中使用以下(简化)GCD调用:

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

        });

});

当呼叫NetworkUtility时,将调用NSURL连接:

 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;

结果是,如果网络收到响应,dispatch_async(dispatch_get_main_queue()块将按预期触发,但如果网络呼叫超时且_recommendationDictionary为零,则dispatch_async(dispatch_get_main_queue()永远不会触发。

如果dispatch_async(dispatch_get_main_queue()返回值,为什么NetworkUtility不会立即触发?

1 个答案:

答案 0 :(得分:1)

该块在主队列上入队。主队列是一个串行队列,它将按顺序执行排队的块。

如果在主线程上使用CFRunLoop,则主调度队列在该运行循环中耗尽,因此如果运行循环被其他活动占用,则还会导致执行这些块的延迟。

如果您实际上不需要在主线程上进行序列化的UI或其他活动,那么最好不要使用主队列。