Reputation: 41510
I have seen common idioms of dispatch_async calling into dispatch_async vs dispatch_async calling into dispatch_sync.
In some circumstances, the latter can be substituted with the former. Question is, in what situation can you only use one and not the other?
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
dispatch_async(dispatch_get_main_queue(), ^{
//
});
});
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
dispatch_sync(dispatch_get_main_queue(), ^{
//
});
});
Upvotes: 1
Views: 211
Reputation: 90681
I would say that you should strive to avoid blocking threads. If you're tempted to use dispatch_sync()
because there's code to run after the stuff you're shunting to the main thread completes, you should instead use "continuation passing" coding style. The task you submit to the main queue should submit a new task to a concurrent queue. So, the code might look like:
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
// A) Some code here
dispatch_async(dispatch_get_main_queue(), ^{
// B) some code here
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
// C) Some code here
});
});
});
The main reason to use dispatch_sync()
is when you're implementing an inherently synchronous interface but you need to dispatch a task to a queue to accomplish that. That usually only happens when you're using a serial dispatch queue (or barrier tasks on a concurrent queue) to protect a shared resource.
Given that the original code already has a dispatch_async()
call, it can't be implementing a synchronous interface.
Upvotes: 1
Reputation: 318944
The 2nd option only makes sense if you have other code inside the dispatch_async
and you want that code executed after the code inside dispatch_sync
completes.
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
// A) Some code here
dispatch_sync(dispatch_get_main_queue(), ^{
// B) some code here
});
// C) Some code here
});
This ensures A is executed, then B (on the main thread), then C (on the background thread but after the B code is done).
If there is no C code, using dispatch_sync
or dispatch_async
for the inner dispatch result in the same thing.
Upvotes: 1