如何在子线程代码块结束后立即执行主线程代码块?

问题描述 投票:0回答:1
    for (int i = 0; i < 20; i++) {
        dispatch_async(queue, ^{

            NSLog(@"xxx");
            dispatch_async(dispatch_get_main_queue(), ^{
                NSLog(@"yyy");
            });
        });
    }

希望打印 "xxx"、"yyy"、"xxx"、"yyy"...。

如何修改?

grand-central-dispatch
1个回答
0
投票

你有几个问题。

首先,你使用的是 dispatch_async(). 该函数将一组代码排队执行。异步 在其他线程上。

这有两个重要的含义。

  • 代码块的执行是不可预测的 它可能在排队的其他代码之前,同时或之后执行
  • 如果 queue 是一个 并发 队列(默认),那么其他19个块也可以同时执行;事实上,所有20个块可能同时运行,但不保证顺序。

为了保证打印 "xxx"、"yyy"、"xxx"、"yyy"、......,必须确保初始块都执行 依次,并且每个子块执行 同步.

所以你的代码需要像这样。

// `queue` must be created as a serial queue
dispatch_queue_t queue = dispatch_queue_create("xxxs",DISPATCH_QUEUE_SERIAL);

for (int i = 0; i < 20; i++) {
    dispatch_async(queue, ^{

        NSLog(@"xxx");
        dispatch_sync(dispatch_get_main_queue(), ^{
            NSLog(@"yyy");
        });
    });
}

循环会立即创建20个代码块并排队,将它们添加到序列号中。queue 顺序。因为 queue 是串行的,队列中每次只执行一个块,第二个队列中的块要等到第一个块完成后才会开始。

当第一个代码块执行完毕后,它打印 "xxx",然后是 同步 排队在主线程上运行一个块。同步调用使线程(第一个块)停止运行,直到该子块在主线程上执行完毕。

一旦 "yyy "块执行完毕,就会有 dispatch_sync 调用返回,第一个代码块恢复执行并退出。第二个代码块在 queue 开始运行,整个过程重复进行,直到所有的块都执行完毕。

说了这么多,因为你想让所有这些代码都按顺序执行,所以创建一个串行队列并添加单个块并没有什么好处。这段代码做的事情是完全一样的,而且更简单。

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0), ^{
    for (int i = 0; i < 20; i++) {
        NSLog(@"xxx");
        dispatch_sync(dispatch_get_main_queue(), ^{
            NSLog(@"yyy");
        });
    }
});

我希望这能帮助你理解队列和同步与异步调度调用。

© www.soinside.com 2019 - 2024. All rights reserved.