Menu

Blog from a passionate developer

Working with Blocks

It’s been a while I wanted to write a note about the “C blocks” but because of lack of time and inspiration I have postponed this task again and again. I’m finally here however. This post aims to provide a summary of what is blocks and how to use them in an Objective-C context. I also took this opportunity to provide a little blocks cheat sheet in order to have a quick access to information.

Blocks? What is that?!

Blocks are a programming concept designed by Apple and added as a nonstandard extension to the C (it means the blocks can also be used in C++, Objective-C 2.0 and Objective-C++). They are natively supported on Mac OS X v10.6 and later, and iOS 4.0 and later.
Trying to be precise and concise a block (also named closure or lambda-expression in another language) is an inline anonymous function which can capture the variables available in its context at the run-time (from the stack and/or the heap).

Why use them?

Blocks are often useful when you need callbacks or delayed execution by passing them as parameters to another methods. Moreover blocks has been designed by Apple in order to make the concurrent programming easier with the GCD (Grand Central dispatch) threading architecture.
Unlike function pointers, blocks are anonymous and can therefore be declared inline on the method call which saves a lot of line of code. Furthermore when you define a block, it makes a snapshot of its current lexical scope which allows you to easily work with variables that surround it.
An another detail which is important during the iOS or Mac development is that in an Objective-C context, blocks are full-fledged objects, meaning they can be copied and retained just like any other object.

All these features make the blocks a very interesting concept in many cases, to make your code more concise and robust and therefore much more readable and maintainable.

Before to show you some example, I’m going to introduce you the syntax of the “C blocks” and explain you on how to read/construct them.

Syntax of blocks

To begin with blocks the most simple is to explain its syntax (people who know the function pointers will not be surprised). Here is the syntax:

The most confusing for a beginner is certainly the block’s declaration. Here the quick steps to declare a block:

Declare a variable: block_name.

Dereference it to yield block information: (^block_name).

Add its return type and its input parameters: type(^block_name) (type_arguments).

The creation is much simpler:

Define that is a block using the caret character: ^.

Mention the return type of the block: ^return_type.

Add the input arguments of the block: ^return_type(typearguments).

Write the block’s body: ^return_type(type arguments) {/* body */}.

Some parts of a block assignment are optionals:

If the block takes no arguments, the argument list can be skipped.

Example: ^BOOL {return YES; }.

You don’t need to specify the return type because it can be inferred by the compiler from the return statement.

Example: ^(NSString *s) {/* body */return YES; }.

The __block Storage Type

One of the characteristics of blocks is that they can capture the variables that are visible to their scope. This is what is called a closure. When you capture a variable, its value is copied into the stack (as a constant), ie you can just read it and not modify it.
Fortunately, you are able to modify the variables inside a block by prefixing them with the__block storage type modifier. This will copy their addresses/references instead of their value.
Let’s make a little example which use the __block keyword to illustrate the concept:

In this example we declare a variable named “x” (prefix with the __block keyword). Then we declare a block named “increment” which caught the “x” variable. Each time we call the “increment” block, the variable is incremented. It’s possible because the variable is prefixed with the __block storage type modifier. If we remove it, the compiler gives us this error: “error: Semantic Issue: Variable is not assignable (missing __block type specifier)“.

Copy / Release

When you create a block, unlike other objects, this one is created on the stack ie that your block will live only within its declaration scope. So if you want use your block everywhere in your code for example you will need to move it on the heap to avoid its deletion. To do so you will have to use the Block_copy C function (We will see later what it will serve you). To avoid a memory leak you must always use a Block_release function with a Block_copy function.

Well, we have talk enough about the theory. The next part will show you how to use them with some example.

Blocks in practice

In this section we are going to show you how to work with blocks (in Objective-C in the most case) using some examples.

Hello World!

To start, here a little block which display a “Hello Wold!” on the console:

This is the easiest way to use a block. In this case, the blocks are anonymous and are called directly after they definition.

Fade a UIView

To illustrate the blocks with a concrete example we are going to work with views. Since iOS 4.0 and the introduction of blocks, Apple has added a lot of convenience API using the powerfull of blocks in order to facilitate our work, like for the view animations. Before, to write a simple fade in (or fade out) animation you needed several line of codes as showing in the sample code bellow:

That’s all! The UIView “animateWithDuration:animations:” method take in first argument the animation duration and in second argument a block which return nothing and take no argument. The block animation capture the aView object and set its alpha to 0.1f. As you can see, you can do the same thing as before but with only “one instruction” thanks to the blocks. If you want learn more about view animation I suggest you visit this post from the Ray Wenderlich’s blog.

Return a block

The blocks are very useful to factor out or make generic pieces of code. To do this, are generally used functions that take input arguments to configure the block which is returned. The following example aims to explain you how and why a function which return a block may be useful.
Imagine that you need functions that just raise a number to a predefined power. With blocks you can create a function which takes an exponent in argument and return a block which takes an integer in input and returns the result of the power of these two numbers. As an example is worth a thousand words, here is the code source:

As you can see, in the first part we declare our function which help us then to create several predefined blocks in the “test” method.
The “blockRaisedToPower” creates firstly a block which closes the exponent (“y” variable) inside its body to use it later in the power calculation. Then the function returns the new block which has just been created. You can noticed that we have used the Block_copy function to move the block from the stack to heap. If we had not done that, the block was deleted at the end of the “blockRaisedToPower” declaration and we would have an EXC_BAD_ACCESS error.
The “test” method simply defines several blocks, here square, cube and zenzizenzizenzic, in order to calculate respectively the x2, x3 and x8. Of course, at the end of this method we have also release the blocks which are on the heap to avoid any leaks. From only one function, this allows you to create different blocks that have been set up at their creation.
Here is the same code but using the typedef and the Objective-C syntax to make the code more readable:

Callbacks

To finish with examples, we are going to talk about the implementation of callbacks (with blocks) using a concrete example.AVAudioPlayer is a nice class to work with audio on iOS which offers only a delegate callback system based. So we are going to add a block callback system in order to make the code more compact.
Here is the YLAudioPlayer.h:

You just have to declare the audio player passing it the delegate block (and the resource) and then play the sound.
This pattern is very simple to deploy in your code, and it can save you a lot of time and pain in the future. You just have to be careful with the memory leaks and when you copy a block you must always release it when you have finished to you it.

Well, I think we have seen the main cases of use for the blocks. Now, we are going to recap the main point relevant to the blocks before to finish.

Summary

To finish, you will find here a small summary of what we have said before. You will find most of the examples in the cheat sheet.

Declaration

// Define a block which return nothing and takes as only argument a NSString *
void (^block_name)(NSString *);
// Doing the same thing using a typedef
typedef void (^MyBlockType)(NSString *);
MyBlockType block_name;

Assignment

Execution

Mistakes to avoid

A block is created by default on the stack and not on the heap. So you have to be careful while using them because in some case your code can compile perfectly, but it does not work during the execution. The following example illustrates this problem:

In this example the block is created either in the if or in the else statement. It means the block is copy into the stack during all the statement’s lifetime and is deleted when the statement is finished (“}“). So when the block is called, it’s already fell of the stack and you’ll have an error. To avoid this error you must use the Block_copy method to move the block from the stack to the heap.

An other issue which can appear is the memory leak if you don’t take care about the reference counting. In Objective-C, when you reference an object (or an instance variable of the object) inside a block, it is retained to prevent its deletion (and so random EXC_BAD_ACCESS error). The following example shows a case where a reference deadlock can appear if you don’t be careful:

Here we created an object of type MyClass which contains two instance variables namely anObject and aBoolean. In the implementation anObject is created using a block which use the aBoolean instance variable. So if the block is retained by the anObject object, a retain cycle can appear. Indeed in this case self will retain the anObject which will hold itself the block, which will keep self because it uses an instance variable of self (See the diagram below).

To avoid this problem, the object variable must be marked with the __block storage type modifier. Using it the object that will be captured will not be retained. So here to avoid the memory leak we create a variable of type MyClass with the __block keyword which will be used onto the block like this:

Conclusion

I hope this article has helped you better understand some aspect of blocks and that the cheat sheet will make your job easier in the future. If you have any question or point to clarify don’t hesitate, comments are here for that. 😉

Thank you very much for your feedback and your share!
Yes, blocks are very useful in a lot of cases. The most difficult part is to assimilate the syntax and to pay attention to some weird cases.
Greetz

I have never fully understood blocks till now. I mean, there is the documentation from Apple itself, but it’s so cryptic I might as well let my Literature teacher include it in our reading list. My exposure to blocks have been limited to code fragments from tutorials and open source projects on the web, which is enough to teach me the basic, but not all there is to know.

Another thing, your blog seems oddly unresponsive. Took me three reloads to view this blog post. Maybe this post got too popular for your server to handle? 😉

ARC manages blocks, like any other objects, and it knows that they have to be copied and not just retained. So in theory you don’t care about them in an ARC context as long as you use block types in your declarations/signatures instead of ‘id’.
For more information you can check this link. 😉