Before we get started, let's take a look at our previous code, once refactored.
Now it looks much better, and most important of all,
it won't crash if we provide a badly formatted URL and NSURL returns a nil.
However, even though it does look good, it still sucks.
It blocks the main queue, so we're going to fix this.
First of all we need to find the line that it's blocking.
Can you spot it just by looking at the code?
Yep.
It's this one.
The NS data one.
That's the one that downloads the hued image and stuff it into an NS data.
We need to send this fellow to background queue.
Actually, the next line where we convert this NS data into a UI image
might also take some time, although much less.
So let's send both to the background.
But hold on, UI image belongs to UI kit.
So we should never use it in the main queue.
Well no, not really.
Not all of UI kit is threat and save.
There are a few exceptions such as UI image.
However all the visual stuff, the views are unsaved.
So changing the image property here, that must be done in the main queue.
Always remember the famous haiku from Zen master Basho.
If the name ends in view it belongs in the main queue.
First of all, let's create a queue from scratch.
So, the first step is to create the URL.
Now that we have the URL we need to create a queue from scratch.
To create a queue from scratch,
we use the function dispatched queue create, and it takes two parameters.
The first one is just a name you can put there whatever you want.
Doesn't really matter, and
the second one tells GCD what kind of queue you want.
Neil in this case tells GCD that we want a synchronous or
a serial queue, otherwise you would have to use
a different constant that you can check on the documentation.
To create an asynchronous queue.
But we're not going to use those in this course.
The following step is to recall dispatch async.
It will take two parameters, the queue, in this case download and the closure.
Although, notice that here I'm using the trailing closure syntax.
So in here is where we need to download the NS data,
turn it into a UA image and then display it.
Let's get started.
Once we have the queue we can call dispatch_async and send,
encapsulate in a closure, the fending code and send it to the background.
However we have a problem here, we're downloading the image
in the background queue, we're turning it into a UI image.
Also in the background queue but we need to run this code and
display this image in the main queue.
How could we do this?
How can we hop from a background queue to the main queue.
Well I've been hinting it for some time.
You gotta think of inception, with dreams within dreams.
In this case it's closures within closures.
So from within the background closure in here,
we're going to get a reference to the main queue, and then call dispatch async
within this closure and send another closure to the main queue.
So basically we're going to start here in the background, and
once we reach this point we're going to jump to the main queue.
Let's see how we can do this.
Let's take a look at this code again.
So, first of all,
we jump to the background, run a few lines of code that will block.
And once we're done with this,
we jump to the main queue using the same function.
Dispatch async.
But this time, we're providing the main queue with dispatch_get_main_queue.
And within this closure, that will run in the main queue,
we set the image for the ImageView.
So this way,
we make sure that all of the code that updates the UI runs in the maiden queue.
So this is not only efficient, it's absolutely safe.
And this is the true beauty of grand central dispatch.
It makes asynchronous code look like it's serial
which is easier to understand one line after the other
while you're actually hopping from one queue to the other queue.
Before we move on, let's make sure that this code actually does not block.
Let's run it and take a look.
So let's try again.
The synchronous, it blocks.
See?
And let's try the asynchronous.
See that it just kind of blips and that's it.
So, even though it seems
like it's instantaneous, it's actually downloading the image in the background.
So let's get here and once we click here it just blinks and
we can, while it's downloading, you can use the, the UI.
So, so far, looks good.
Let's move to the next step and implement this last method.
This is kind of your graduation for this lesson.
It's an asynchronous method with a completion closure.
Let's give it a try.