Multithreading and Grand Central Dispatch on iOS for Beginners Tutorial

Have you ever written an app where you tried to do something, and there was a long pause while the UI was unresponsive? This is usually a sign that your app needs multithreading! In this tutorial, you’ll get hands on experience with the core multithreading API available on iOS: Grand Central Dispatch. You’ll take an […] By Ray Wenderlich.

Leave a rating/review
Save for later
Share
You are currently viewing page 3 of 3 of this article. Click here to view the first page.

Dispatch Queues, Locks, and Cat Food

A dispatch queue is set up by default to be serial – this means only one block of code from the queue runs at a time. This can be pretty convenient, because you can use this behaviour to protect shared data.

If you aren’t familiar with locks in multithreading, think back to our earlier example about cats. What would happen if two cats wanted to go to the cat food dish at the same time? Big problems, that’s what!

But what if we made all of our cats get in a line instead. And we’d say “hey cat, if you want to access this cat dish, you have to stand in this line!” If only life were this easy!

Maybe GCD really stands for Grand Cat Dispatch?

Maybe GCD really stands for Grand Cat Dispatch?

That’s the basic idea behind using dispatch queues to protect data. You set up your code so that a particular data structure is only accessed by code running within a particular dispatch queue. Then since dispatch queues run blocks serially, you’re guaranteed that only one will access the data structure at a time.

In this app we have two data structures we have to protect:

  1. The linkURLs array inside ImageListViewController. To protect this, we’ll structure our code so that this is only ever touched in the main thread.
  2. The pendingZips variable inside ImageManager. To protect this, we’ll structure our code so that this is only ever touched in our “backgroundQueue”.

OK enough chat about Grand Central Dispatch – let’s try it out!

Grand Central Dispatch in Practice

Start by opening up ImageGrabber.h and make the following changes:

// Add to top of file
#import <dispatch/dispatch.h>

// Add new instance variable
dispatch_queue_t backgroundQueue;

To use Grand Central Dispatch, you first need to import . We also predeclare the dispatch queue we’ll be using to run our background processing tasks.

Next open up ImageGrabber.m and make the following changes:

// 1) Add to bottom of initWithHTML:delegate
backgroundQueue = dispatch_queue_create("com.razeware.imagegrabber.bgqueue", NULL);        

// 2) Add to top of dealloc
dispatch_release(backgroundQueue);

// 3) Modify process to be the following
- (void)process {    
    dispatch_async(backgroundQueue, ^(void) {
        [self processHtml];
    });    
}

// 4) Modify call to processZip inside retrieveZip to be the following
dispatch_async(backgroundQueue, ^(void) {
    [self processZip:data sourceURL:sourceURL];
});

// 5) Modify call to delegate at the end of processHTML **AND** processZip to be the following
dispatch_async(dispatch_get_main_queue(), ^(void) {
    [delegate imageInfosAvailable:imageInfos done:(pendingZips==0)];
});

These are all simple but important calls, so let’s discuss each one in turn.

  1. This creates the dispatch queue. When you create a dispatch queue you need to give it a unique name as a string. One good way to create unique names is to use reverse DNS notation like this.
  2. When you create a dispatch queue, don’t forget to release it! For this queue we’ll release it when the ImageManager is deallocated.
  3. The old process just ran processHTML directly, hence ran it in the main thread blocking the UI as the HTML was parsed. Now, we run it in the background on the backgroundQueue we created, with a simple call to dispatch_async!
  4. Similarly, after we download the zip we get a callback in the main thread from ASIHTTPRequeset saying “hey, I’m done!” Instead of blocking the UI as we save and unzip the zip file like we did before, now we run it on the background queue. This is also important to make sure that the pendingZips variable is protected.
  5. We want to make sure that we call the delegate method within the context of the main thread. First, to make sure that the linkURLs array in the view controller is only accessed via the main thread, according to our strategy discussion earlier. Second because that method interacts with UIKit objects, and UIKit objects can only be used by the main thread.

That’s it! Compile and run your code, and ImageGrabber should behave much more responsively!

A responsive app with Grand Central Dispatch

But Wait!

If you’ve been programming on iOS for a while, you may have heard of these fancy things called NSOperations, and operation queues. You might wonder when you should use them, and when you should use Grand Central Dispatch.

Well, NSOperations are simply an API built on top of Grand Central Dispatch. So when you’re using NSOperations, you’re really still using Grand Central Dispatch.

It’s just that NSOperations give you some fancy features that you might like. You can make some operations dependent on other operations, reorder queues after you sumbit items, and other things like that.

In fact, ImageGrabber is already using NSOperations and operation queues! ASIHTTPRequest uses them under the hood, and you can configure the operation queue it uses for different behavior if you’d like.

So which should you use? Whichever makes sense for your app. For this app it’s pretty simple so we just used Grand Central Dispatch directly, no need for the fancy features of NSOperation. But if you need them for your app, feel free to use it!

Where To Go From Here?

Here is a sample project with all of the code from the above tutorial.

You now have some practical experience with using asynchronous operations and grand central dispatch on iOS. But this tutorial has barely scratched the surface – there’s a lot more you can learn!

I’d first suggest listening to the great Apple videos related to Grand Central Dispatch. Both WWDC 2010 and 2011 have some videos that are a great introduction to what’s available.

And if you really want to get into things, Mike Ash has some great articles on Grand Central Dispatch that you might want to check out.

If you have any questions, comments, or suggestions, please join the forum discussion below!

Contributors

Over 300 content creators. Join our team.