Async Await in Swift

Hasancan Akgündüz
2 min readMar 12, 2022

Apple introduced a new way of handling asynchronous tasks using async and await keywords. Basically, we mark the asynchronous functions with async and call them with await keyword.

The old way of handling asynchronous tasks using completion closures has an important downside that we have to call the callback in each exit, if not our app might wait forever for the closure to end. Async methods is promising to replace it and resolve this issue.

I will show with an example of fetching an image from network:

The old way with completion closure callbacks:

Here, OldPresenter calls fetchImage function of OldDataProvider and when completion callback is called it sets the image.

And, here is how we implement with the new async/await mechanism:

We no longer have a completion parameter. Instead, fetchImage function throws error and it is marked with async keyword. Inside the function, we are using the new URLSession api that is compatible with new async/await feature.

In loadImage function, we mark the expression calling fetchImage function with await and the fetchImage needs to be called in a asynchronous calling environment. That’s why we enclose it in Task.

Memory Management

See that in previous example in line 15, the image is assigned to a local variable and then in the following line, it is assigned to our instance property. This is to prevent the async function to keep a strong reference to our Presenter instance. Let’s see the behaviour in detail:

In here, after loadImage function exits, our instance does not wait for async function to finish and it gets deallocated. Let’s see another example:

Here, our instance does not get allocated until async function gets completed. The important point is, although we hold weak reference of our instance inside Task closure, the async function still holds our instance strong. (which in my opinion is confusing and prone to error.)

--

--