What's the difference between synchronous and asynchronous calls in Objective-C, versus multi-threading?

Doug Smith picture Doug Smith · Jan 14, 2014 · Viewed 74.5k times · Source

For the longest time I thought asynchronous was synonymous to running something on a background thread, while synchronous meant on the main thread (blocking UI updates and interactions). I understand that not running on the main thread for expensive actions is because it doesn't allow UI actions to occur as the main thread is occupied, but why is synchronous troublesome?

However, it's since came to my attention that you can make asynchronous calls on the main thread, and synchronous calls on background threads.

I always hear people saying not to use expensive calls synchronously or on the main thread, as it will block the UI for the user. Are these two separate issues I should be making sure I don't do? What are the differences?

Answer

Rob picture Rob · Jan 14, 2014

When you invoke something synchronously, it means that the thread that initiated that operation will wait for the task to finish before continuing. Asynchronous means that it will not wait.

Having said that, when people suggest that you perform some slow or expensive process asynchronously, they are implicitly suggesting not only that you should run it asynchronously, but that you should do that on a background thread. The goal is to free the main thread so that it can continue to respond to the user interface (rather than freezing), so you are dispatching tasks to a background thread asynchronously.

So, there are two parts to that. First, using GCD as an example, you grab a background queue (either grab one of the global background queues, or create your own):

// one of the global concurrent background queues

dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

// or you could create your own serial background queue:
//
// dispatch_queue_t queue = dispatch_queue_create("com.domain.app.queuename", 0);

Second, you dispatch your tasks to that queue asynchronously:

dispatch_async(queue, ^{
    // the slow stuff to be done in the background
});

The pattern for operation queues is very similar. Create an operation queue and add operations to that queue.

In reality, the synchronous vs asynchronous distinction is completely different from the main queue vs background queue distinction. But when people talk about "run some slow process asynchronously", they're really saying "run some slow process asynchronously on a background queue."