dispatch_sync总是在主线程上调度一个块

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

串行队列(也称为私有调度队列)按照将其添加到队列中的顺序一次执行一个任务。 当前正在执行的任务运行在由调度队列pipe理的不同线程上(可能因任务而异)。

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

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

  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 }); 

输出 –

  Main Thread Main Thread Main Thread // Main Thread printed till didReceiveData: gets called 

  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 }); 

输出 –

  Main Thread Main Thread Main Thread // Main Thread printed till didReceiveData: gets called 

我在这里有点惊讶,块总是在主线上执行,或者我错过了一些东西。 因为它似乎是在反对苹果文件,我认为是这样。 有谁知道这是什么?

更新 :根据其他讨论,我明白,dispatch_sync在同一个线程(大部分时间)执行一个块,然后为什么苹果文档的声明在某些方面是矛盾的。 为什么苹果说:“ 当前正在执行的任务运行在一个不同的线程(这可能因任务而异)由调度队列pipe理 。 还是我还想念什么?

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

编辑

苹果的文档不仅说这个,还说这个:

作为优化,该函数尽可能地调用当前线程上的块。

作为一个方面的说明(我知道你在谈论的同步版本,但让我们精确到这一点)我会说,也dispatch_async()可能会导致多个块在同一个线程中执行。

对于背景块,请使用

 dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ // background code }); 

注意它是_async而不是_sync

编辑:同样,要执行主线程上的东西,使用

 dispatch_async(dispatch_get_main_queue(), ^{ // main thread code }); 

意识到Grand Central Dispatch可以保证提交到主队列的块将在主线程上运行,但是提交给其他队列的块不能保证块将在哪个线程上执行。

不能保证块将被调用的线程。 但是,一次只能调用一个提交给FIFO调度队列的数据块。

Grand Central Dispatchpipe理线程池并尽可能重用现有线程。 如果主线程可用于工作(即空闲),则可以在该线程上执行一个块。

这里是你如何在Swift中做到这一点:

 runThisInMainThread { () -> Void in // Runs in the main thread } func runThisInMainThread(block: dispatch_block_t) { dispatch_async(dispatch_get_main_queue(), block) } 

它包括在我的回购标准function,检查出来: https : //github.com/goktugyil/EZSwiftExtensions