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:

type (^block_name) (type_arguments) = ^return_type(type arguments) { /* body */ };

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

  1. Declare a variable: block_name.
  2. Dereference it to yield block information: (^block_name).
  3. Add its return type and its input parameters: type (^block_name) (type_arguments).

 

The creation is much simpler:

  1. Define that is a block using the caret character: ^.
  2. Mention the return type of the block: ^ return_type.
  3. Add the input arguments of the block: ^ return_type (type arguments).
  4. 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:

__block int x = 0; // Use the __block keyword to be able to modify it into the block

// Create a block to increment the given variable
void (^increment) () = ^ { x++; };

NSLog(@"%d", x); // Display "0"
increment();
NSLog(@"%d", x); // Display "1"

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:

^ void (void) {
   NSLog(@"Hello World!"); // Print "Hello World!"
}(); // () calls the block

// Equivalent block because it returns nothing and it takes no arguments
^ {
   NSLog(@"Hello World!"); // Print "Hello World!"
}(); // () calls the block

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:

[aView setAlpha:1.0f]; // Set the initial view's alpha

[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:2.0f];

[aView setAlpha:0.01f]; // Set the final view's alpha

[UIView commitAnimations]; // Commit and run the animation

Now, to do the same thing with CocoaTouch and the blocks it is very simple. In the following example we have a UIView with an original alpha of 1.0f that we will fade to 0.01f in 2 seconds:

[aView setAlpha:1.0f]; // Set the initial view's alpha

[UIView animateWithDuration:2.0f
                     animations:^ { [aView setAlpha:0.01f]; }];

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:

- (int (^) (int))blockRaisedToPower:(int)y
{
   int (^block) (int) = ^ int (int x)
   {
       return pow(x, y); // Close the value of "y"
   };
   return Block_copy(block); // Attention: You have to copy the block to the heap
                             // if you want be able to use it elsewhere in your code 
}

- (void)test
{
   int (^square) (int) = [self blockRaisedToPower:2];
   int (^cube) (int) = [self blockRaisedToPower:3];
   int (^zenzizenzizenzic) (int) = [self blockRaisedToPower:8];

   NSLog(@"%d", square(3));           // 9
   NSLog(@"%d", cube(3));             // 27
   NSLog(@"%d", zenzizenzizenzic(3)); // 6561

   // Don't forget to release the blocks returned
   Block_release(square);
   Block_release(cube);
   Block_release(zenzizenzizenzic);
}
Note: Zenzizenzizenzic means x8 (cf: wikipedia).

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:

typedef NSInteger (^PBlock) (NSInteger); // Define a new block type named "PBlock"

- (PBlock)blockRaisedToPower:(NSInteger)y
{
   PBlock block = ^ NSInteger (NSInteger x)
   {
       return pow(x, y);
   };
   return [[block copy] autorelease]; // copy is equivalent to Block_copy(block) in Objective-C
                                      // We autorelease the block to respect the best practices of Cocoa Touch
}

- (void)test
{
   PBlock square = [self blockRaisedToPower:2];
   PBlock cube = [self blockRaisedToPower:3];
   PBlock zenzizenzizenzic = [self blockRaisedToPower:8];

   NSLog(@"%d", square(3));           // 9
   NSLog(@"%d", cube(3));             // 27
   NSLog(@"%d", zenzizenzizenzic(3)); // 6561
}

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:

#import <AVFoundation/AVFoundation.h>

typedef void (^YLAudioPlayerBlock)(BOOL);

@interface YLAudioPlayer : AVAudioPlayer 
{
@protected
    YLAudioPlayerBlock delegateBlock;
}

- (id)initWithContentsOfURL:(NSURL *)fileURL usingBlock:(YLAudioPlayerBlock)delegate;
+ (id)audioPlayerWithContentsOfURL:(NSURL *)fileURL usingBlock:(YLAudioPlayerBlock)delegate;

@end

In the interface, we have just define 2 new methods in order to use a block as callback and a new block as instance variable of the player.

Here is the corresponding YLAudioPlayer.m:

#import "YLAudioPlayer.h"

@interface YLAudioPlayer ()
@property (nonatomic, copy) AudioPlayerBlock delegateBlock; // Attention: Copy the block and not retain it
@end

@implementation YLAudioPlayer
@syntesize delegateBlock;

- (void)dealloc
{
    // Release the block because it has been copied
    [delegateBlock release], delegateBlock = nil;

    [super dealloc];
}

- (id)initWithContentsOfURL:(NSURL *)fileURL usingBlock:(YLAudioPlayerBlock)delegate
{
   if ((self = [super initWithContentsOfURL:fileURL error:nil]))
   {
      self.delegateBlock = delegate;
      self.delegate = self;
   }

    return self;
}

+ (id)audioPlayerWithContentsOfURL:(NSURL *)fileURL usingBlock:(YLAudioPlayerBlock)delegate
{
    return [[[self alloc] initWithContentsOfURL:fileURL  usingBlock:delegate] autorelease];
}

#pragma mark -
#pragma mark YLAudioPlayer Delegate Methods

- (void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)player successfully:(BOOL)flag
{
    // Call the delegate
    delegateBlock(flag);
}

@end

The 2 main method here are the init and the delegate method:

  • initWithContentsOfURL:usingBlock: Create the new audio player, set itself as delegate and set copy the delegate block.
  • audioPlayerDidFinishPlaying:successfully: When this delegate method is call, we call the delegate block.

To know how to use this class let’s go by writing a sample code:

YLAudioPlayer *ap = 
[YLAudioPlayer audioPlayerWithContentsOfURL:aSoundResourceURL usingBlock: ^ (BOOL successfully)
{
    if (successfully)
    {
        // do something
    }
}];

[ap play]; // Play the sound

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

// Assigning this block to the block_name variable
block_name = ^ void (NSString *parameter) { /* body */ };

Execution

// Call the block passing a NSString * as parameter
block_name(@"parameter name");

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:

void (^block_name) ();
if (...)
{
   block_name = ^ { ... };
} else
{
   block_name = ^ { ... };
}
block_name();

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.

void (^block_name) ();
if (...)
{
   block_name = [^ { ... } copy]; // move the block on the stack
} else
{
   block_name = [^ { ... } copy]; // move the block on the stack
}
block_name();

[block_name release]; // When you copy a block, think to release it

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:

// MyClass.h instance variables
WhateverObject *anObject;
BOOL aBoolean;

// MyClass.m
anObject = [[WhateverObject alloc] initWithBlock: ^
{
   NSLog(@"%d", aBoolean); // Possible retain cycle
}];

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).

Reference cycles which leads to memory leaks

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:

// MyClass.h instance variables
WhateverObject *anObject;
BOOL aBoolean;

// MyClass.m
__block MyClass *selfBlockRef = self; // trick
anObject = [[WhateverObject alloc] initWithBlock: ^
{
   NSLog(@"%d", selfBlockRef->aBoolean);
}];

The Cheat Sheet!

Before I forget, here is the download link: Block Cheat Sheet

It summarizes the main points which has been talked about before:

  • Block definition
  • Block declaration
  • Block creation
  • Block call
  • Block storage type modifier
  • Block copy / release
  • Mistakes to avoid

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. 😉

References

For further study or clarify some points you can follow these links:

1 Star2 Stars3 Stars4 Stars5 Stars (9 votes, average: 4.67 out of 5)
Loading...

22 comments

Cancel

Time limit is exhausted. Please reload CAPTCHA.

This site uses Akismet to reduce spam. Learn how your comment data is processed.

  1. Johann · November 13, 2011

    Nice work on the cheat sheet, you will definitely save a lot of headaches with that. Blocks really are so amazing.

    • Yannick Loriot · November 13, 2011

      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

  2. Pingback: Handy Cheat Sheet For Using Objective-C Blocks (Closures) | iPhone, iOS 5, iPad SDK Development Tutorial and Programming Tips
  3. Stefan · November 13, 2011

    GREAT work, thanks a lot!

    Only one little issue: “mistakes to avoid” – the “deadlock” isn’t really a deadlock but a retain cycle, is it?

    • Yannick Loriot · November 13, 2011

      Hey, thanks for the feedback.
      Yes you have right, it’s my bad. I’m going to fix that now. 😉

  4. Pingback: Handy Cheat Sheet For Using Objective-C Blocks (Closures) | WebScriptPlus.com
  5. vignesh · November 13, 2011

    Neat explanation. Organized concepts well. Useful.

  6. Pingback: A Post on Objective-C Blocks « allforios
  7. AddictiveColors · November 13, 2011

    Very nice tutorial and blocks cheat sheet :), thanks.

    • Yannick Loriot · November 13, 2011

      Thank you! It tooks a lot of times to do such articles so if it can be helpful that’s

  8. Tom · November 13, 2011

    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? 😉

    P.S. YOUR CAPTCHA MADE ME DO MATH YUCK

    • Yannick Loriot · November 13, 2011

      Hi,
      Thank your for your feedback! I’m glad it helped you to clarify some points.

      I don’t think have enough traffic on my blog to slow down the bandwidth (so may be a host problem), but if the issue becomes more recurent I’ll look at it more closely.

      Thank you, again,
      Yannick

      P.S. Without captcha I receive a lot of spam and this one is understandable (In my opinion).

  9. Thomas Torp · November 13, 2011

    When doing the “return a block example” under ARC. Do you still have to copy the block or will the compiler handle it?

    For me I get it to work with both approaches. So what is the correct way?

    • Yannick Loriot · November 13, 2011

      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. 😉

  10. turygo · November 13, 2011

    pretty cool job.Thank you for your share.

  11. Akshay shah · November 13, 2011
  12. abdus · November 13, 2011

    Hi, Very nice article. Thanks for writing

  13. Greak · November 13, 2011

    Really good article, but I would like to ask, how can I catch the return value of a method call that has two blocks as parameters??

    ex.

    typedef void (^AlertRowBlock)(NSIndexPath *selectedIndex);
    typedef NSArray *(^AlertCompletionBlock)(bool cancelOrOKButton);

    -(void)configureSelectionBlock:(AlertRowBlock)selBlock
    andCompletionBlock:(AlertCompletionBlock)comBlock;

    So, I would like to have access to the variable that is returned after the call to “AlertCompletionBlock”.

    Do you know how to??

    Thanks!!

  14. Pingback: My Favourite iOS Tutorials | Anoop4Real
  15. Pingback: iOS/ Obj C Quick reference and Cheat sheets | Anoop4Real
  16. Pingback: (转)Github上的热门iOS开源项目:AFNetworking、MagicalRecord、BlocksKit以及XVim | 一起火吧
  17. Pingback: Github上的热门iOS开源项目:AFNetworking、MagicalRecord、BlocksKit以及XVim-IT大道