ios main_queue 上的 dispatch_async?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/15169925/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-30 22:31:55  来源:igfitidea点击:

dispatch_async on main_queue?

ios

提问by nine stones

I have seen this code snippet:

我见过这个代码片段:

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

This doesn't look like making much sense to me.

这对我来说似乎没有多大意义。

EDIT: To clarify the conditions of my question:

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

  • The call to dispatch_asyncis performed from the main thread.
  • The sent message doSomeNetworkStuffis the heavy lifting worker task.
  • ... and is not only the UI-updating task.
  • 调用dispatch_async是从主线程执行的。
  • 发送的消息doSomeNetworkStuff是繁重的工人任务。
  • ... 不仅是 UI 更新任务。

Dispatch, sure, but using the main queue would just pull the dispatched task back to the ui thread and block it.

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

Please, am I missing something? Thanks.

请问,我是不是遗漏了什么?谢谢。

采纳答案by nine stones

I lost track of this question, but as it still gets traction, I'll post an answer to this (using swift)

我忘记了这个问题,但由于它仍然受到关注,我会发布一个答案(使用 swift)

Assumptions: I do know that UI work has to be done on the main thread.

假设:我知道 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()
}

Taking all this together IMHO the original code does not make very much sense. It could be replaced with:

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

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

The original async dispatch onto the main thread to then dispatch to background should be wasteful and confusing (obviously).

最初的异步调度到主线程然后调度到后台应该是浪费和混乱的(显然)。

Unfortunately I am not in the position anymore to try this out with the original code base.

不幸的是,我不再能够使用原始代码库进行尝试。

Am I missing an idea here?

我在这里错过了一个想法吗?

回答by Alex

dispatch_asynclets your app run tasks on many queues, so you can increase performance. But everything that interacts with the UI must be run on the main thread. You can run other tasks that don't relate to the UI outside the main thread to increase performance.

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

});

回答by Alessandro Ornano

Swift 3:

斯威夫特 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")
    }
}

回答by user1826351

when you want to do some Webservicecall or something you dispatch a async call like this below:

当你想要做一些 Webservicecall 或其他事情时,你可以像下面这样调度异步调用:

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

Now, suppose you want to update or push a ViewController from your dispatched thread, if you directly push viewcontroller from this, app will or may get crashed,as such UI updates should be done in main thread of app,below is the answer for this then.

现在,假设您想从调度线程更新或推送 ViewController,如果您直接从这里推送 ViewController,应用程序将会或可能会崩溃,因此 UI 更新应该在应用程序的主线程中完成,以下是对此的答案然后。

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
});

});

for detail visit : blackberrymastercracks.blogspot.in

详情请访问:blackberrymastercracks.blogspot.in

回答by Muhammad Usman Aleem

It depends from where this code is being called. Means if its calling from main queue then it doesn't make sense. (Note: it will not cause a crash but it will just add a task in main queue ).

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

If this code is written in background thread then this is a converging point for the application. Like you are getting data from web service in background thread then wants to update it on UI then you can call it.

如果这段代码是在后台线程中编写的,那么这是应用程序的一个收敛点。就像您在后台线程中从 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];
     });
}

You can find more details over apple documentation https://developer.apple.com/library/ios/documentation/General/Conceptual/ConcurrencyProgrammingGuide/OperationQueues/OperationQueues.htmlor from this answer also https://stackoverflow.com/a/19822753/505735

您可以找到有关苹果文档的更多详细信息https://developer.apple.com/library/ios/documentation/General/Conceptual/ConcurrencyProgrammingGuide/OperationQueues/OperationQueues.html或从这个答案也https://stackoverflow.com/a/ 19822753/505735

Do post me if its still unclear. I will write a detailed answer.

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

回答by Richard Brown

You'll usually see that syntax inside of another dispatch_asynccall that runs on a background thread. This is because all updates to the UI should happen on the main thread, not in the background.

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