1

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(), ^{
       //
    });
});

2 Answers 2

1

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.

Sign up to request clarification or add additional context in comments.

1 Comment

If there is no C code, the logical effect is the same, but the practical effect is that you kept a thread occupied but doing nothing.
1

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.