You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何dispatch_get_main_queue异步块执行顺序与预期不符?

为什么主队列异步任务的输出顺序是1、2、3而不是1、3、2?

先看你的代码:

- (void)viewDidLoad { 
    [super viewDidLoad]; 
    NSLog(@"1"); 
    dispatch_async(dispatch_get_main_queue(), ^{ 
        NSLog(@"3"); 
    }); 
    NSLog(@"2"); 
}

哈哈这个问题我刚接触GCD的时候也困惑过!核心原因得从主队列的本质和dispatch_async的工作机制说起:

  • 首先,主队列是一个串行队列,而且它的所有任务都只会在主线程上执行。串行队列的特点是:必须等当前正在执行的任务完全结束,才会取下一个任务执行。
  • 其次,dispatch_async的作用是把任务异步提交到指定队列的末尾,它不会阻塞当前的执行流程——也就是说,提交完任务后,当前代码会继续往下走,不会等着这个新任务执行。

现在我们一步步拆解你的代码执行流程:

  1. 进入viewDidLoad,先调用[super viewDidLoad];,然后执行NSLog(@"1");,控制台输出1。
  2. 调用dispatch_async(dispatch_get_main_queue(), ^{ NSLog(@"3"); });:这时候你是把打印3的block提交到主队列的任务末尾。但注意,当前主队列正在执行的任务就是viewDidLoad这个方法本身,所以这个新的打印任务必须等viewDidLoad里的所有同步代码都执行完,才会被轮到执行。
  3. 继续执行NSLog(@"2");,控制台输出2。
  4. 等viewDidLoad整个方法执行完毕,主队列的当前任务结束了,这时候才会从队列里取出刚才提交的block,执行NSLog(@"3");,输出3。

如果换成dispatch_sync(同步提交)到主队列,那结果就会是1、3、2了——因为同步提交会阻塞当前任务,必须等提交的任务执行完,当前代码才会继续往下走。但异步提交不会,它只是“排队”,等当前任务干完再轮到它。


内容的提问来源于stack exchange,提问作者yong ho

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 08:08:19