dispatch_sync总是在主线程上调度一个块
我正在使用dispatch_sync执行一个块,并且块被正确执行。 但是这个块在主线程上执行。 根据Apple Doc:
串行队列(也称为私有调度队列)按照将其添加到队列中的顺序一次执行一个任务。 当前正在执行的任务运行在由调度队列pipe理的不同线程上(可能因任务而异)。
这意味着(或我所理解的)当前正在执行的进程将在单独的线程上运行。
下面是我用来判断发生了什么的代码。 它在NSURLConnection的didReceiveData: delegate方法中被调用(我知道我不应该在didReceiveData:delegate方法内部这样做 – 但这只是一个关注dispatch_sync的示例)。 以下是我可以作为我的结论certificate的不同方式:
-
在全局并发队列上使用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
-
在使用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