Coding with Blocks in Objective-C

By Peng Xie

Part I

There are two things to mention before we start:

  1. This blog is for readers with intermediate knowledge of Objective-C and memory management. However, readers with knowledge of other programming languages or even without any programing experience may still enjoy the blog and get a flavor of the block concept.
  2. This blog assumes the coding is done under Automatic Reference Counting (ARC) environment. ARC can greatly simplify memory management work. Apple encourages developers using ARC for projects. Most tutorials and libraries are using ARC. So of course we are going to use ARC in this blog.

Getting Started with Blocks

Introduced in iOS 4.0 and OS X 10.6, blocks have become a great way to reduce code and dependency on delegates. Like functions or enclosures in other programming languages, blocks encapsulate data and codes inside themselves so they can be used as callbacks or executed concurrently. Blocks are treated as first-class functions in Objective-C. That means blocks can be assigned to variables, passed as parameters and returned from functions and methods as Objective-C objects.

Creating a block is fairly straightforward once you get used to the caret (^) symbol. In Objective- C syntax, the ^ symbol means “block.” Below is a picture from Apple’s iOS Developer Library illustrating how to create a block.

Creating Blocks

Creating Blocks

As you can see from the picture, the int (^myBlock)(int) is the declaration of the block and ^(int num) {return num * multiplier;} is the definition. The block has an int type parameter called “num” and it will return an int type value. There you have a block and you can call it by simply doing “myBlock(5)” just like calling a function. (The parameter “5” can be any value or variable.)

Another feature you will notice from the picture is how blocks interact with variables. Other than the parameters passed in, blocks also have access to local and global variables. Here comes the confusing part: Blocks will copy local variables as const type inside the blocks themselves. Only by giving the variables a “__block” storage modifier can you change values of variables from within the block. And when working with Objective-C objects, the block will make a strong reference to “self” if you access an instance variable by reference or the block will make a strong reference to the variable when you access an instance variable by value. If you are not careful with these “rules”, you may end up getting some pretty messy memory management issues. You can see that in an example in the last part of the blog. For now, let’s move on and talk about some benefits of using blocks.
Maybe you will ask, how can blocks simplify the code and why do we want to use them. Let’s look at this example of how blocks simplify the iteration of an array.

“Traditionally”, we can iterate over an array using a for loop:

For Loop

For Loop

Or, we can also iterate over an array using the fast-enumeration in Objective-C:

Fast Enumeration

Fast Enumeration

Now, using blocks:

Block Enumeration

Block Enumeration

As shown above, we used the built-in method “enumerateObjectsUsingBlock:” of NSArray class to iterate over the array. When using the traditional for loop or fast-enumeration, we have direct access to either the index or the object. However, by using blocks, we can get access to both the object and the index with less coding. One thing worth mentioning is the “stop” parameter for the block in “enumerateObjectsUsingBlock:”. The developer can set the “stop” to YES from within the block to stop the iteration. In addition, there is a speed advantage when using blocks to iterate over an array. Under complex cases, the advantage can become significant.

Blocks and Concurrency

As mentioned in the beginning of this blog, blocks can be executed concurrently. Before we dive into the topic of blocks and concurrency, let’s change gear to talk about the concurrency concept a little bit. Concurrency means multiple things happening at the same time. In the world of Objective-C, developers use APIs like dispatch queues and operation queues to execute multiple tasks at the same time. Dispatch queues are part of the popular Grand Central Dispatch technology provided in Objective-C and require the submitted tasks to be encapsulated inside a block object. While using dispatch queues is pretty main stream and straight forward, operation queues can be complicated, but at the same time, more interesting, especially when working together with blocks.

Where To Go From Here?

In this part of the blog, we went through some basics of blocks, discussed how to use blocks and why they are a better choice for coding. We also briefly introduced the concept of concurrency and how developers execute blocks concurrently by using APIs provided in Objective-C. Make sure to come back and check out the second part of the blog, where we will look into the operation queues and blocks to see how NSBlockOperation can help us concurrently execute blocks. There will also be a bonus chapter in part two of this blog to show a pitfall you can easily run into when dealing with NSBlockOperation. And of course we’re going to show you how to deal with that pitfall to make sure you won’t get into that bad situation.

Advertisements

One thought on “Coding with Blocks in Objective-C

  1. Pingback: Cogent Blog Corner | Coding with Blocks in Objective-C (Part 2)

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s