main_queue上的dispatch_async?

时间:2013-03-02 02:12:47

标签: ios

我看过这段代码:

dispatch_async(dispatch_get_main_queue(), ^{
    [self doSomeNetworkStuff];
});

这看起来对我来说没什么意义。

编辑:澄清我的问题的条件:

  • dispatch_async的调用是从主线程执行的。
  • 发送的消息doSomeNetworkStuff是繁重的工作任务。
  • ...并且不仅仅是UI更新任务。

派遣,当然,但是使用主队列只会将调度的任务拉回到ui线程并阻止它。

拜托,我错过了什么吗? 感谢。

6 个答案:

答案 0 :(得分:33)

dispatch_async可让您的应用在多个队列上运行任务,因此您可以提高性能。 但是,与UI交互的所有内容都必须在主线程上运行。 您可以运行与主线程外部的UI无关的其他任务,以提高性能。

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{

  //Add some method process in global queue - normal for data processing

    dispatch_async(dispatch_get_main_queue(), ^(){
    //Add method, task you want perform on mainQueue
    //Control UIView, IBOutlet all here

    });

 //Add some method process in global queue - normal for data processing

});

答案 1 :(得分:8)

Swift 3

DispatchQueue.global(attributes: .qosBackground).async {
    print("This is run on the background queue")

    DispatchQueue.main.async {
        print("This is run on the main queue, after the previous code in outer block")
    }
}

答案 2 :(得分:5)

当你想做一些Webservicecall或你发送异步调用时,如下所示:

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0),^{
        //Call your webservice here , your app will not freeze at all  
});

现在,假设你想要从你的调度线程更新或推送一个ViewController,如果你直接从这个推送viewcontroller,app会或者可能会崩溃,因为这样的UI更新应该在app的主线程中完成,下面是那么回答。

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0),^{
       //Call your webservice here , your app will not freeze at all

       //To update UIFrom dispatched Thread:

       dispatch_async(dispatch_get_main_queue,^{   

       //Push view controller here
});

});

详细信息请访问:blackberrymastercracks.blogspot.in

答案 3 :(得分:5)

这取决于调用此代码的位置。意味着如果它从主队列调用那么它没有意义。 (注意:它不会导致崩溃,但它只会在主队列中添加一个任务)。

如果此代码是在后台线程中编写的,那么这是应用程序的聚合点。就像你从后台线程中的Web服务获取数据然后想要在UI上更新它然后你可以调用它。

-(void) backgroundThreadFunction {

     //Some stuff on background thread. 

     dispatch_async(dispatch_get_main_queue(), ^{
         //Wants to update UI or perform any task on main thread.    
         [self doSomeNetworkStuff];
     });
}

您可以在Apple文档https://developer.apple.com/library/ios/documentation/General/Conceptual/ConcurrencyProgrammingGuide/OperationQueues/OperationQueues.html上找到更多详细信息 或者从这个答案中https://stackoverflow.com/a/19822753/505735

如果仍然不清楚,请发帖我。我会写一个详细的答案。

答案 4 :(得分:2)

您通常会在后台线程上运行的另一个dispatch_async调用中看到该语法。这是因为UI的所有更新都应该在主线程上进行,而不是在后台进行。

答案 5 :(得分:0)

我没有跟踪这个问题,但是由于它仍然很受关注,我将对此问题发布答案(使用快速方法)

假设:我确实知道UI工作必须在主线程上完成。

//
// We are on the main thread here.
// The following will schedule the closure on the main thread after ALL other 
//   routines currently scheduled on the main thread are done. 
//
DispatchQueue.main.async {
    //
    // So here we are back on the main thread AFTER all routines on the main 
    //   thread have completed.
    // 
    // If the following call does NOT dispatch onto a background thread 
    //    it will block the UI and it was really bad programming.
    // 
    // Thus, for now and for the benefit of the doubt, let's assume 
    //   `doSomeNetworkStuff()` DOES dispatch to a background thread.
    //   
    // This can only make sense if the the func `doSomeNetworkStuff()` 
    //   relies on results of code paths following this current 
    //   `DispatchQueue.main.async(... we are here ...)`.
    //
    // If `doSomeNetworkStuff()` does NOT depend on any other code paths:
    //   Why not directly scheduling it directly on a background thread? 
    //   Which is unnecessary, as as stated above it MUST dispatch on to the
    //     background anyways.
    // 
    // Moreover, there is few possibility that `doSomeNetworkStuff()` does 
    //   depend on other codepaths, because `self` is already captured by 
    //   the closure.
    //
    self.doSomeNetworkStuff()
}

将所有这些放在一起恕我直言,原始代码没有多大意义。可以替换为:

// We are on the main thread here
self.doSomeNetworkStuff()

将原始异步分派到主线程然后分派到后台应该是浪费和混乱的(显然)。

不幸的是,我无法再使用原始代码库来尝试此操作了。

我在这里想念吗?