简体   繁体   中英

What's the point in using dispatch_async + dispatch_get_main_queue for UI updates?

I'm seeing quite a lot of dispatch blocks after successful network requests using AFNetworking (with blocks) in the codebase I need to work with:

-(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.

    });
  }
}

From what I know, we don't need explicitly to set callback code to be executed on main thread because AFNetworking already performs callbacks on main thread. The only reason I see here is to allow parent method to finish its work and "a little bit" to delay these UI updates (putting them into the end of main thread queue). But we probably don't need do that, so these dispatch_async should be removed IMHO. Any ideas on that?

Generally for asynchronous network requests, this is necessary, because the callbacks happen on a background thread. However, AFNetworking should always be calling the response blocks on the main thread, so it should be completely unnecessary to do this in your own code when using AFNetworking. It may have been that the code you're using previously used a different library where the callbacks didn't come on the main thread, or used custom written code even, so it's probably just leftover. Either that or the previous developer didn't know that the AFNetworking callbacks came on the main thread. So it should be safe to remove it.

Any framework or library that is across-the-board calling blocks on specific threads, without being incredibly obvious about it, is doing something very wrong, IMHO.

However, in AFNetworking's specific case it looks like they took the 80/20 rule -- the default callback queue is on the main thread (it's using NSOperationQueue behind the scenes). In other words, AFNetworking does not call blocks on the main queue -- it calls them on the configured queue. If the default configured queue is not modified or set by the end developer, then the operation runs on the main thread.

To change this, simply set the completionQueue on the AFHTTPRequestOperation instance.

If you have a very heavily threaded app, you may likely be managing your own work queue, which you pass to AFNetworking. Especially in these cases, dispatching the UI updates on the main thread is vital (as it always is).

Yes AFNetworking blocks are executed on main thread until you set completionQueue to AFHTTPRequestOperation. If you are not doing anything fancy (like full background network code that should not lock the main thread) you don't have to use that block in your logic.

Network operations of course are done in separate thread not locking until response comes, but completion and failure blocks are executed always on main thread by default.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM