使用dispatch_async + dispatch_get_main_queue进行UI更新有什么意义?

时间:2014-02-19 14:15:23

标签: ios objective-c grand-central-dispatch

在我需要使用的代码库中使用AFNetworking(带有块)成功进行网络请求后,我看到了很多调度块:

-(void)someMethodThatPerformsNetworkRequest{

  networkManager.newsList getNewsCallBack:^{

    // Store received and parsed data...

    // Do UI updates. IMHO it's not necessary to warp it inside dispatch_async
    dispatch_async(dispatch_get_main_queue(), ^(){

      // Some UI updates
      // ... table reloads, label changes and etc.

    });
  }
}

据我所知,我们不需要显式设置要在主线程上执行的回调代码,因为AFNetworking已经在主线程上执行回调。我在这里看到的唯一原因是允许父方法完成其工作并“一点点”延迟这些UI更新(将它们放入主线程队列的末尾)。但我们可能不需要那样做,所以这些dispatch_async应该被删除恕我直言。有什么想法吗?

3 个答案:

答案 0 :(得分:1)

通常对于异步网络请求,这是必要的,因为回调发生在后台线程上。但是,AFNetworking应始终在主线程上调用响应块,因此在使用AFNetworking时,在您自己的代码中完成此操作应该完全没必要。可能是您以前使用的代码使用了不同的库,其中回调没有出现在主线程上,或者甚至使用自定义编写的代码,所以它可能只是剩下的。无论是那个还是以前的开发人员都不知道AFNetworking回调出现在主线程上。所以删除它应该是安全的。

答案 1 :(得分:1)

任何在特定线程上全面调用块的框架或库,并没有令人难以置信地显而易见,它正在做一些非常错误的事情,恕我直言。

然而,在AFNetworking的特定情况下,看起来他们采用了80/20规则 - 默认回调队列在主线程上(它在幕后使用NSOperationQueue)。换句话说, AFNetworking不会调用主队列上的块 - 它会在配置的队列上调用它们。如果默认配置的队列未被最终开发人员修改或设置,则操作将在主线。

要更改此设置,只需在AFHTTPRequestOperation实例上设置completionQueue

如果你有一个非常强大的线程应用程序,你可能会管理自己的工作队列,并将其传递给AFNetworking。特别是在这些情况下,在主线程上调度UI更新至关重要(一如既往)。

答案 2 :(得分:0)

是AFNetworking块在主线程上执行,直到您将completionQueue设置为AFHTTPRequestOperation。如果您没有做任何花哨的事情(例如不应该锁定主线程的完整后台网络代码),则不必在逻辑中使用该块。

网络操作当然是在单独的线程中完成,直到响应到来才锁定,但默认情况下总是在主线程上执行完成和失败块。