【问题标题】:Purpose of running dispatch_async(dispatch_get_main_queue() on UI Thread在 UI 线程上运行 dispatch_async(dispatch_get_main_queue() 的目的
【发布时间】:2015-05-14 09:19:48
【问题描述】:

在实际情况下,dispatch_async(dispatch_get_main_queue() 是在 UI 线程上实现的,这是很常见的。我不知道它的用途。

我的想法是既然UI线程上只有一个线程,那么dispatch_async的目的是什么?

举一个我几天前在这里遇到的真实例子:

在 UI 线程上运行“NSTimer scheduledTimerWithTimeInterval”以更新“_scrollView contentOffset”

1 无调度: setContentOffset 在下一个 NSTimer 计划之前生效

2 带调度: setContentOffset 立即生效

【问题讨论】:

  • 你能提供一些上下文吗?也许代码可以从后台线程运行,这样只是为了安全。否则可能只是延迟代码,直到布局引擎有时间运行。
  • 我上面已经举了一个例子

标签: ios


【解决方案1】:

dispatch_async(dispatch_get_main_queue(), ... ) 强制代码块在主线程(UI 线程)的下一个运行循环中异步运行。某些代码必须在 UI 线程上运行,例如从 UI 添加/删除小部件或更新 UI。

dispatch_async( .. ) 用于不阻塞当前线程。

【讨论】:

  • 在实践和现实中,我发现这种方式可以在 UI 线程忙于其他几个任务时加快执行速度,即使它没有意义。
【解决方案2】:
dispatch_async(dispatch_get_main_queue(),
                       ^{
                           // perform something on UI
                       });

dispatch_async 是一个低级 GCD API(Grand Central Dispatch API)。正如我们所知,应用程序主线程用于在 UI 上执行任何活动,例如执行动画/任何其他与 UI 相关的内容,因此在使用 UI 进行一些工作的上下文中,它应该能够访问主线程以及 GCD 之上的内容API 是否为 UI 提供对主线程的相同保证访问以执行任何相关操作。

【讨论】:

    【解决方案3】:

    GCD 到主队列通常是从后台队列完成的,以表明某些后台处理已经完成。例如

     dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0),^{
        // Here you are doing a very expensive operation which will take let say 5 secs. And after 5 sec you will got your result. Let say
    
        int output = //calculated result.
    
        dispatch_async(dispatch_get_main_queue(), ^{
               [[self myLable] setText:[NSString stringWithFormat:@"%d", output]];     
        });
    });
    

    在这种情况下,我们正在后台队列上进行冗长的计算,以免阻塞主线程。得到结果后,我们需要更新 UI。 UIKit 不应从任何其他线程访问,应从 main thread 访问,以避免竞争条件并防止在访问 UIKit 期间崩溃。所以这里我们使用dispatch_async 让主线程有机会通过dispatch_get_main_queue() 工作。

    【讨论】:

      【解决方案4】:

      我个人在另一个 dispatch_async(background, non-UI thread) 中使用它 - 当我执行计算或任何可以在后台线程上运行的事情时然后我想“回来”并相应地更新 UI,dispatch_async(dispatch_get_main_queue()...) 将我返回到 UI 线程,因此我可以更新 UI。否则,如果我在第一个 dispatch_async 中停留在后台线程上,则不会对 UI 进行任何更改。

      【讨论】:

        【解决方案5】:

        可能代码“dispatch_async”不在主线程上,dispatch_get_main_queue 保证块中的代码在主线程上运行。

        它喜欢performselectonmainthread,

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2015-10-21
          • 2020-02-19
          • 1970-01-01
          • 2012-05-21
          相关资源
          最近更新 更多