Ios dispatch\u sync始终在主线程上调度块
我正在使用dispatch_sync执行一个块,并且该块执行正确。但是这个块是在主线程上执行的。根据苹果文件: 串行队列(也称为专用调度队列)执行一个任务 按它们添加到队列中的顺序进行最新版本 当前正在执行的任务在一个不同的线程上运行(可能会有所不同) 从一个任务到另一个任务),由调度队列管理。 这意味着(或者我所理解的)正在执行的当前进程将在一个单独的线程上运行 下面是我用来判断发生了什么的代码。它是在NSURLConnection的didReceiveData:delegate方法中调用的(我知道我不应该在didReceiveData:delegate方法中这样做,但这只是一个关注dispatch\u sync的示例)。以下是我可以假设的证明我的结论的不同方式:Ios dispatch\u sync始终在主线程上调度块,ios,objective-c,cocoa-touch,cocoa,grand-central-dispatch,Ios,Objective C,Cocoa Touch,Cocoa,Grand Central Dispatch,我正在使用dispatch_sync执行一个块,并且该块执行正确。但是这个块是在主线程上执行的。根据苹果文件: 串行队列(也称为专用调度队列)执行一个任务 按它们添加到队列中的顺序进行最新版本 当前正在执行的任务在一个不同的线程上运行(可能会有所不同) 从一个任务到另一个任务),由调度队列管理。 这意味着(或者我所理解的)正在执行的当前进程将在一个单独的线程上运行 下面是我用来判断发生了什么的代码。它是在NSURLConnection的didReceiveData:delegate方法中调用的(
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
});
// 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
Main Thread
Main Thread
Main Thread
// Main Thread printed till didReceiveData: gets called
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
});
// 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
Main Thread
Main Thread
Main Thread
// Main Thread printed till didReceiveData: gets called
我在这里有点惊讶,块总是在主线程上执行,或者我遗漏了什么。因为这似乎与苹果公司的做法背道而驰,我想是的。有人知道这是怎么回事吗 更新:根据其他讨论,我了解dispatch_sync在同一线程上执行一个块(大多数情况下),那么为什么apple docs的声明在某些方面相互矛盾。为什么苹果说“当前正在执行的任务运行在一个由调度队列管理的不同线程上(任务之间可能有所不同)。” 还是我仍然缺少什么?dispatch\u sync()在同一个线程上调度块,这很正常 编辑 苹果的文档不仅如此,还说: 作为优化,此函数在可能的情况下调用当前线程上的块
作为旁注(我知道您谈论的是同步版本,但让我们澄清一下),我要说的是,dispatch_async()也可能导致在同一线程中执行多个块 对于背景块,使用
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
// background code
});
注意,它是异步的,而不是同步的
编辑:同样,要在主线程上执行某些操作,请使用
dispatch_async(dispatch_get_main_queue(), ^{
// main thread code
});
重要的是要认识到,Grand Central Dispatch可以保证提交到主队列的块将在主线程上运行,但提交到任何其他队列的块不能保证块将在哪个线程上执行 不保证在哪个线程上调用块;但是,可以保证一次只调用提交给FIFO调度队列的一个块
GrandCentralDispatch管理线程池并尽可能重用现有线程。如果主线程可用于工作(即空闲),则可以在该线程上执行块 以下是如何在Swift中执行此操作:
runThisInMainThread { () -> Void in
// Runs in the main thread
}
func runThisInMainThread(block: dispatch_block_t) {
dispatch_async(dispatch_get_main_queue(), block)
}
它作为一个标准功能包含在我的回购协议中,请查看:我已经提到它只是为了专注于调度同步。我知道我可以使用dispatch_async(dispatch_get_main_queue()@Ismael,如果dispatch_async(dispatch_get_main_queue(),…)来实现它是从主队列中调用的。根据文档,如果我读对了,这将导致死锁。不,它不会导致死锁。很可能它将被添加到主线程队列中,并在线程释放后进行处理。啊,我已经知道了,但它与apple doc相矛盾。我不认为这是一个矛盾,而是一个aff信息(粗体部分)您不能为所用队列选择目标线程,也不能保证其一致性。不过,请针对文档提交一个bug并要求澄清这一点。@JoshuaNozzi我认为您是正确的。我需要提交一个bug并要求clarification@RamyAlZuhouri你在上面引用的观点——它是否也写在文档中iOS,因为我只在Mac开发文档中见过它。@Evol Gate它在两个文档中都有写:iOS和OS X。可能NSThread不知道队列…@vikingosegundo“不知道”是什么意思?NSThread是一个旧的软件,而dispatch_queues是新的。也许NSThreads只是不知道queues,或者至少不完全知道—我不知道,只是一个想法。或者正如Ramy在他的编辑中指出的那样,您的示例不能像您预期的那样工作。@quelish您的答案有意义吗……您想分享您的评论参考吗苹果文档链接?Thanks@NisarAhmad,它在标题中:以及
人工调度队列\u创建@quelish:如果主线程可能在主队列以外的其他队列中使用,是否意味着当时关联的当前循环是MainRunLoop?(我知道循环与线程关联)