Reputation: 3438
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:
dispatch_async
is performed from the main thread.doSomeNetworkStuff
is the heavy lifting worker task.Dispatch, sure, but using the main queue would just pull the dispatched task back to the ui thread and block it.
Please, am I missing something? Thanks.
Upvotes: 33
Views: 50996
Reputation: 3438
I lost track of this question, but as it still gets traction, I'll post an answer to this (using swift)
Assumptions: I do know that UI work has to be done on the main thread.
//
// 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?
Upvotes: -1
Reputation: 35402
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")
}
}
Upvotes: 8
Reputation: 197
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.
-(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.html or from this answer also https://stackoverflow.com/a/19822753/505735
Do post me if its still unclear. I will write a detailed answer.
Upvotes: 5
Reputation: 1171
dispatch_async
lets 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(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
});
Upvotes: 39
Reputation: 91
when you want to do some Webservicecall or something you dispatch a async call like this below:
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.
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
Upvotes: 6
Reputation: 11444
You'll usually see that syntax inside of another dispatch_async
call that runs on a background thread. This is because all updates to the UI should happen on the main thread, not in the background.
Upvotes: 3