大中央调度主线程

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (11)

我在应用程序中成功地使用了大型中央调度,但我想知道使用这样的东西真正的优势是什么:

dispatch_async(dispatch_get_main_queue(), ^{ ... do stuff

甚至

dispatch_sync(dispatch_get_main_queue(), ^{ ... do stuff

都要在主线程上触发一个块,这将无助于减少负载。在第一种情况下,无法控制块何时运行。我见过在你解雇他们后半秒钟内就有一些街区被执行的案例。第二种情况,类似于

[self doStuff];

对吗?

提问于
用户回答回答于

向主队列发送块通常是从后台队列执行的,以指示某些后台处理已经完成。

- (void)doCalculation
{
    //you can use any string instead "com.mycompany.myqueue"
    dispatch_queue_t backgroundQueue = dispatch_queue_create("com.mycompany.myqueue", 0);

    dispatch_async(backgroundQueue, ^{
        int result = <some really long calculation that takes seconds to complete>;

        dispatch_async(dispatch_get_main_queue(), ^{
            [self updateMyUIWithResult:result];
        });    
    });
}

在这种情况下,我们正在对后台队列进行冗长的计算,并且需要在计算完成后更新UI。更新UI通常必须从主队列中完成,因此我们使用第二个嵌套分派将“信号”返回到主队列,异步。

可能还有其他一些例子,您可能希望将其重新分派回主队列,但通常都是这样做的,即嵌套在分派到后台队列的块中。

  • 后台处理完成->更新UI
  • 在后台队列上处理的数据块->信号主队列启动下一个块
  • 后台队列上的传入网络数据->消息已到达的主队列信号
用户回答回答于

从主线程向主队列分派块要有用。它使主队列有机会处理其他已排队的块,这样就不会简单地阻止其他所有块的执行。

例如,可以编写一个本质上是单线程的服务器,但它仍然处理许多并发连接。只要队列中没有单独的块占用太长时间,服务器就会响应新的请求。

如果你的程序只做了一辈子的事情,那么这是很自然的。只需将事件处理程序设置为在主队列上运行,然后调用分派。_Main(),可能根本不需要担心线程安全。

扫码关注云+社区