为什么在主队列上调用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_async
, viewWillLoad
放弃主队列并使其可用于块运行。
在串行队列(如主队列)上使用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中的主线程上运行