dispatch_sync始终在主线程上调度块

Evo*_*ate 10 cocoa cocoa-touch objective-c grand-central-dispatch ios

我正在使用dispatch_sync执行一个块,并且块正确执行.但是这个块在主线程上执行.根据Apple Doc:

串行队列(也称为专用调度队列)按照将它们添加到队列的顺序一次执行一个任务.当前正在执行的任务在由调度队列管理的不同线程(可能因任务而异)上运行.

这意味着(或我所理解的)当前正在执行的进程将在一个单独的线程上运行.

下面是我用来判断发生了什么的代码.它在NSURLConnection的didReceiveData: delegate方法中被调用(我知道我不应该在didReceiveData:delegate方法中这样做 - 但这只是一个关注dispatch_sync的示例).以下是我可以假设的不同方式作为我的结论的证明:

  1. 全局并发队列上使用dispatch_sync

       dispatch_sync(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
    
            if ([NSThread isMainThread]) {
                NSLog(@"Main Thread");
            }
            else
                NSLog(@"Not on Main Thread");
    
            //Some Process
        });
    
    Run Code Online (Sandbox Code Playgroud)

输出 -

         Main Thread
         Main Thread 
         Main Thread
         // Main Thread printed till didReceiveData: gets called
Run Code Online (Sandbox Code Playgroud)
  1. 使用dispatch_queue_create在自己创建的队列上使用dispatch_sync

    // Create queue somewhere else like this
    dispatch_queue_t newQueue = dispatch_queue_create("WriteQueue", DISPATCH_QUEUE_SERIAL);
    
    
       dispatch_sync(newQueue, ^{
    
            if ([NSThread isMainThread]) {
                NSLog(@"Main Thread");
            }
            else
                NSLog(@"Not on Main Thread");
    
            //Some Process
        });
    
    Run Code Online (Sandbox Code Playgroud)

输出 -

         Main Thread
         Main Thread 
         Main Thread
         // Main Thread printed till didReceiveData: gets called
Run Code Online (Sandbox Code Playgroud)

我在这里有点惊讶,块总是在主线程上执行或者我错过了什么.因为它似乎与Apple Doc相反,我想是这样的.有谁知道这是什么一回事?

更新:根据其他讨论我理解dispatch_sync在同一个线程上执行一个块(大多数时候),那么为什么apple docs的语句在某些方面是矛盾的.为什么apple说"当前正在执行的任务在由调度队列管理的不同线程(可能因任务而异)上运行." 还是我还缺少什么?

Ram*_*uri 15

dispatch_sync()在同一个线程上调度该块,这是正常的.

编辑

Apple的文档不仅说明了这一点,还说:

作为优化,此函数在可能的情况下调用当前线程上的块.

作为旁注(我知道你在谈论同步版本,但让我们先说明这一点)我会说,dispatch_async()也可能导致在同一个线程中执行多个块.


Ism*_*ael 5

对于背景块,请使用

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
    // background code
});
Run Code Online (Sandbox Code Playgroud)

注意它是_async而不是_sync

编辑:同样,要在主线程上执行某些操作,请使用

dispatch_async(dispatch_get_main_queue(), ^{
    // main thread code
});
Run Code Online (Sandbox Code Playgroud)