5

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

我定义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_sync()的函数时,在并发队列上触发的函数块内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()独立调用时主线程阻塞?

4

5 回答 5

4

dispatch_sync串行队列(如主队列)上使用时,当前线程必须等到分派的代码被执行。

当一个块从串行队列同步分派到同一个队列时,就会发生死锁。

于 2013-09-11T12:17:16.710 回答
3

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

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

于 2013-09-11T12:19:11.153 回答
0

只需要明白这一点:

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

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

于 2013-09-11T12:21:57.020 回答
0

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

由于您正在使用dispatch_syncthis 进行调度,因此将是一个阻塞调用dispatch_sync

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

于 2013-09-11T12:17:30.110 回答
0

当您运行异步任务时,它将创建一个新线程,并且您在块中的代码将在该新线程中执行。在该方法中,您调用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 中的主线程上运行

于 2017-01-25T02:30:58.280 回答