How to Use Block Objects in Your iOS App

By Jesse Feiler

Objective-C blocks are like traditional C functions in that blocks are small, self-contained units of code in your iOS app. They can be passed in as arguments of methods and functions and then used when they’re needed to do some work. (Like many programming topics, understanding block objects is easier when you use them.)

With iOS 4 and newer versions, a number of methods and functions of the system frameworks are starting to take blocks as parameters, including the following:

  • Completion handlers

  • Notification handlers

  • Error handlers

  • Enumeration

  • View animation and transitions

  • Sorting

Here, you get to use a block-based method to animate a car, but block objects also have a number of other uses, especially in Grand Central Dispatch and the NSOperationQueue class, the two recommended technologies for concurrent processing. Feel free to check out concurrent processing.

One of the values of using blocks is that you can access local variables (as well as instance variables), which you can’t do in a function or a callback. You also don’t have to pass data around — a block can modify variables to pass data back. In addition, if you need to change something, there’s no API to change, with its concomitant ripple effect.

Sometimes it’s easier to follow what’s happening by declaring a block variable and passing that as the argument to the method. The declaration syntax, however, is similar to the standard syntax for function pointers, except that you use a caret (^) instead of an asterisk pointer (*).

If you look at animateWithDuration:animations:completion: in the UIView class reference, you’ll see

+ (void)animateWithDuration:(NSTimeInterval)duration
 animations:(void (^)(void))animations
 completion:(void (^)(BOOL finished))completion;

Apple is now treating blocks as a primary design pattern, up there with inheritance and delegation — so don’t be surprised to find blocks being used more and more.

Nevertheless, because it’s a tad advanced, the code is investigated in depth so you’ll be comfortable with blocks, despite the really weird syntax.

To start, this is the syntax that defines animations as a block that has no parameters and no return value:

void (^)(void))animations

completion is defined as a block that has no return value and takes a single Boolean argument parameter:

 (void (^)(BOOL finished))completion

When you create a block inline, you just use the caret (^) operator to indicate the beginning of a block and then follow with the code enclosed within the normal braces. That’s what was going on with

animations:^ {
 self.car.center = center;
}

and

completion:^(BOOL finished){
 [self rotate];
}

Although in this example you use blocks inline, you could also declare them like any other local variable. Add the code in bold to your testDrive method replacing what you already have in that spot.

- (IBAction)testDrive:(id)sender {
 CGPoint center = CGPointMake(car.center.x,
 self.view.frame.origin.y + car.frame.size.height/2);
 void (^animation)()= ^() {
 self.car.center = center;
 };
 void (^completion)(BOOL) = ^(BOOL finished){
 [self rotate];
 };
 [UIView animateWithDuration:3 animations:animation 
         completion:completion];
}

When you declare a block, you use the caret (^) operator to indicate the beginning of a block with the code enclosed within the normal braces, and a semicolon to indicate the end of a block expression.

The declaration in Listing 10-2 is pretty much the same as you see in the following animateWithDuration:animations:completion: method declaration, except that the identifiers have been moved around a little. Both are bolded to make that a little easier to see:

+ (void)animateWithDuration:(NSTimeInterval)duration
  animations:(void (^)(void))animations
  completion:(void (^)(BOOL finished))completion;

Here, you’re declaring two block variables by using the ^ operator: one with the name of animations that has no return value, and one with the name of completion that has no return value and takes BOOL as its single argument:

void (^animation)()
void (^completion)(BOOL)

This is like any other variable declaration (int i = 1, for example), in which you follow the equal sign with its definition.

You use the ^ operator again to indicate the beginning of the block literal — the definition assigned to the block variable. The block literal includes argument names (finished) as well as the body (code) of the block and is terminated with a semicolon:

void (^animation)() = ^() {
 self.car.center = center;
};
void (^completion)(BOOL) = ^(BOOL finished){
 [self rotate];
};

After you do get the hang of blocks, you’ll find all sorts of opportunities to use them to simplify your code.