我有一个使用 AFNetworking 发送请求的应用程序,在完成下载后,它调用块我从JSON创建数据模型 . 在模型初始化期间,使用以下代码加载异步图像

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
   NSData *urlData = [NSData dataWithContentsOfURL:downloadURL];
}

我知道 dataWithContentsOfURL: 是同步的,并且符合https://developer.apple.com/library/mac/documentation/Cocoa/Reference/Foundation/Classes/NSData_Class/#//apple_ref/occ/clm/NSData/dataWithContentsOfURL

...这个方法可以在慢速网络上阻塞当前线程数十秒......

但是因为它阻止了主线程 . 经过一番调查,我发现从位于 AFURLSessionManager.m 内的 URLSession:task:didCompleteWithError: 方法开始,具有以下块层次结构

URLSession:task:didCompleteWithError: //1
    |
   dispatch_async(url_session_manager_processing_queue(), ^{  //2
   //url_session_manager_processing_queue() - this is the default queue
       |
      dispatch_group_async(url_session_manager_completion_group(), dispatch_get_main_queue(), ^{ //3
          |
         //Inside of my callback
         dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ //4
            |
           NSData *urlData = [NSData dataWithContentsOfURL:downloadURL];

如果我设置 AFHTTPSessionManagercompletionQueue 属性:

_sharedClient.completionQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

然后 dispatch_group_sync ... //3 使用默认队列,而不是主线程和主线程没有被阻止 . 有人解释为什么没有设置 completionQueue 属性我的主线程被阻止? (在主线程中显示 semaphore_wait_trap 的堆栈跟踪)