我看过这段代码:
dispatch_async(dispatch_get_main_queue(), ^{
[self doSomeNetworkStuff];
});
这看起来对我来说没什么意义。
编辑:澄清我的问题的条件:
dispatch_async
的调用是从主线程执行的。doSomeNetworkStuff
是繁重的工作任务。派遣,当然,但是使用主队列只会将调度的任务拉回到ui线程并阻止它。
拜托,我错过了什么吗? 感谢。
答案 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)
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
});
});
答案 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()
将原始异步分派到主线程然后分派到后台应该是浪费和混乱的(显然)。
不幸的是,我无法再使用原始代码库来尝试此操作了。
我在这里想念吗?