代码之家  ›  专栏  ›  技术社区  ›  纪忠懿

为什么Dispatch\u group\u notify在不同的环境中工作不同?

  •  1
  • 纪忠懿  · 技术社区  · 7 年前

    第一种情况是,我创建了一个命令行工具应用程序,并运行此代码。

        NSLog(@"Main:%@", [NSThread currentThread]);
    
        dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
        dispatch_group_t group = dispatch_group_create();
    
        dispatch_group_async(group, queue, ^{
            NSLog(@"Task1:%@", [NSThread currentThread]);
        });
    
        dispatch_group_async(group, queue, ^{
            NSLog(@"Task2:%@", [NSThread currentThread]);
        });
    
        dispatch_group_notify(group, dispatch_get_main_queue(), ^{
            NSLog(@"Finish:%@", [NSThread currentThread]);
        });
    

    登录终端为

        Main:<NSThread: 0x1028033b0>{number = 1, name = main}
        Task2:<NSThread: 0x10040f0f0>{number = 2, name = (null)}
        Task1:<NSThread: 0x1006008d0>{number = 3, name = (null)}
    

    如果我想显示上次登录 queue 并更换 main queue

         dispatch_group_notify(group, dispatch_get_main_queue(), ^{
            NSLog(@"Finish:%@", [NSThread currentThread]);
        });
    

    具有 队列

         dispatch_group_notify(group, queue, ^{
            NSLog(@"Finish:%@", [NSThread currentThread]);
        });
    

    终端打印最后一个日志。但为什么它不能在主队列中撤销?

    当我将此代码复制到简单的iOS应用程序时。所有工作正常:

    Main:<NSThread: 0x600000070ac0>{number = 1, name = main}
    Task2:<NSThread: 0x6000002633c0>{number = 3, name = (null)}
    Task1:<NSThread: 0x600000263480>{number = 4, name = (null)}
    MainFinish:<NSThread: 0x600000070ac0>{number = 1, name = main}
    

    我尝试添加 sleep(1) 在“命令工具行”中的Task1上,但它似乎阻止了队列并仅打印日志:Task2。。。。但这一切在简单的iOS应用程序中都能很好地工作。

    为什么会导致这些不同?

    1 回复  |  直到 7 年前
        1
  •  1
  •   jimmy    7 年前

    image here

    与创建时处于活动状态的其他队列不同,您应该调用 dispatch_main() 执行提交给主线程的块的方法

    image here

    相同代码在iOS应用程序中运行良好的原因是,应用程序启动一个默认runloop,该runloop根据UI更新通知等特定规则执行提交给主队列的任务。

    参考如下:

    swift-corelibs-libdispatch

    Concurrency Programming Guide