Multithreading in iOS – Part 5

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:

1. Network Manager

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:

2. Nested Closure

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:

3. Nested Closure Output

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:

4. Operation Queue in combination with Dispatch Group

In the above example:

  1. We create first, second, third operations and a dispatch group
  2. Inside the first operation block, we add group.enter() indicating that the block has entered.
  3. Once the completion from taskOne is returned, we add group.leave() indicating that the block has left the group
  4. Here since the taskTwo is dependent on taskOne and taskThree is dependent on taskTwo,  we add group.wait() before coming out of the firstOperation as shown in line no 31 and also before coming out of secondOperation as shown in line no 41
  5. Then we add the dependencies between the tasks, like secondOperation is dependent on the firstOperation and thirdOperation is dependent on the secondOperation to finish.
  6. 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:

5. Output

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:

  1. Introduction to multithreading 
  2. Grand Central Dispatch
  3. Dispatch Group
  4. Operation Queues

Leave a Comment

Your email address will not be published. Required fields are marked *