为什么在主队列上调用dispatch_sync()会阻塞主队列?

我知道这不是一个强烈的问题,但我必须清楚这个概念。

我已经定义了myBlock如下。

 void(^myBlock)(void) = ^{ for(int i = 0;i < 10 ; i++) { NSLog(@"%d and current queue = %@",i,[NSThread currentThread]); } }; 

现在在viewDidLoad方法中,当我在主队列上独立使用dispatch_sync()方法时,主队列被阻塞。

这是样本。

 - (void)viewDidLoad { [super viewDidLoad]; dispatch_queue_t queue = dispatch_get_main_queue(); dispatch_sync(queue,myBlock); } 

但是,当我在主线程上使用相同的dispatch_async()函数时,在并发队列上触发的dispatch_async()函数块中,主线程不会被阻塞。

这是样本。

 - (void)viewDidLoad { [super viewDidLoad]; dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); dispatch_async(queue,^{ dispatch_sync(dispatch_get_main_queue(),myBlock); }); } 

我不清楚为什么会这样? 独立调用dispatch_sync()时为什么主线程被阻塞?

只有一个主队列。 在您的第一个示例中, viewDidLoad正在其上运行。 然后告诉viewDidLoad等待(即“同步”)其他将在主队列上运行的东西。 它们都不能同时在它上面。

在您的第二个示例中,它是被告知等待的并发队列。 这不是问题,因为通过执行dispatch_asyncviewWillLoad放弃主队列并使其可用于块运行。

在串行队列(如主队列)上使用dispatch_sync时,当前线程必须等待,直到执行调度的代码。

当从同步队列同步调度块到同一队列时,会发生死锁。

在主队列上调度块相当于在主线程上调用它。 主队列在主线程上执行。

由于您使用dispatch_sync进行dispatch_sync因此这将是一个阻塞调用dispatch_sync

提交块对象以在调度队列上执行,并等待该块完成。

只需要了解这一点:

dispatch_sync()阻塞调度队列,向其提交块并等待直到提交的块完成。

dispatch_async()在调度队列上提交异步执行块并立即返回。

当您运行异步任务时,它将创建一个新线程,并且该块中的代码将在该新线程中执行。 在该方法中,您在主线程上调用dispatch_sync ,因为您希望在主队列中运行。 请尝试通过此示例了解它。

 dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(void) { if ([NSThread isMainThread]) { NSLog(@"Running on main Thread in dispatch_async"); } else { NSLog(@"Running on another Thread in dispatch_async"); } dispatch_sync(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(void) { if ([NSThread isMainThread]) { NSLog(@"Running on main Thread in dispatch_sync"); } else { NSLog(@"Running on another Thread in dispatch_sync"); } }); dispatch_sync(dispatch_get_main_queue(), ^(void) { if ([NSThread isMainThread]) { NSLog(@"Running on main Thread in dispatch_sync"); } else { NSLog(@"Running on another Thread in dispatch_sync"); } }); }); 

输出是:

在dispatch_async中的另一个线程上运行
在dispatch_sync中的另一个线程上运行
在dispatch_sync中的主线程上运行