Dispatch group and operation queue
There are times when we come across a situation in the project, where we need to execute multiple tasks one after another. Like download the image first and then process the image.
In the above scenario, we can see a clear dependency that the image processing depends on the download task to finish first. In these kind of dependency scenarios, most of the time we choose a nested closure approach where output of the first task acts as an input to the second task.
Let us take a look at the Network Manager class as below:
![](https://icodentest.com/wp-content/uploads/2022/07/Network-Manager-1-929x1024.png)
In the above Network Manager class, we have three functions.
To simulate the task function delay, we have an array [1,2,3,4].
In each function, we get the random element in this array and wait here in this method for this many seconds by using sleep method before calling the completion.
Now let us call these tasks one after another in the View Controller as shown below:
![](https://icodentest.com/wp-content/uploads/2022/07/Nested-Closure.png)
In the above example, each tasks are executed one after another in the form of a nested closure. This will do the required task, but in case we need to execute more tasks one after another, then it is not a good approach to have nested closure. The code readability is compromised and would lead to some confusion due to so many closing braces.
The output of the method will look like below:
![](https://icodentest.com/wp-content/uploads/2022/07/Nested-Closure-Output-1024x339.png)
As we can see above, the tasks are executed one another and the result is achieved. But is there is a better approach with better code readability ?
And the answer is YES. We could use Dispatch Group in combination with Operation Queues to achieve this.
Operation Queue in combination with Dispatch Group
Let us have a Operation Queue and dispatch group in the View Controller as shown below:
![](https://icodentest.com/wp-content/uploads/2022/07/Screenshot-2022-07-24-at-10.25.44-PM-1015x1024.png)
In the above example:
- We create first, second, third operations and a dispatch group
- Inside the first operation block, we add
group.enter()
indicating that the block has entered. - Once the completion from
taskOne
is returned, we addgroup.leave()
indicating that the block has left the group - Here since the
taskTwo
is dependent ontaskOne
andtaskThree
is dependent ontaskTwo
, we addgroup.wait()
before coming out of thefirstOperation
as shown in line no 31 and also before coming out ofsecondOperation
as shown in line no 41 - Then we add the dependencies between the tasks, like
secondOperation
is dependent on thefirstOperation
andthirdOperation
is dependent on thesecondOperation
to finish. - At last we create the Operation Queue and add the operations as shown above.
Since we have the dependency between the tasks, operation queue will handle these automatically and the tasks are executed one by one. The result is as shown below:
![](https://icodentest.com/wp-content/uploads/2022/07/Operation-Queue-and-DG-output-1024x363.png)
As we can see above, the tasks are executed one after another.
If you have missed my previous blog posts on multithreading, you can have a look at those below: