These are some notes I took from Lecture 10 of Paul Hegarty’s excellent iPhone App Dev course. Go there for the full story.

What is a block?

Is a chunk of code that is usually inlined, but can be passed around like an argument to methods.
It’s very smart about local variables, referenced objects.

What does it look like?

Here’s a method I want to pass a block to:

[aDictionary enumerateKeysAndObjectUsingBlock:^(id key, id value, BOOL *stop) {
  NSLog(@"value for key %@ is %@", key, value);
  if (([@"ENOUGH" isEqualToString:key]) {
    *stop = YES;
  }
}];

This method exists in NSDictionary. It basically enumerates through each element in a Dictionary and allows you to pass it a block with will be applied on each element.

Block starts with magical caret ^. Means a block.

Can use local variables declared before the block inside the block

double stopValue = 53.5;
[aDictionary enumerateKeysAndObjectUsingBlock:^(id key, id value, BOOL *stop) {
  NSLog(@"value for key %@ is %@", key, value);
  if (([@"ENOUGH" isEqualToString:key] || ([value doubleValue] == stopValue) {
    *stop = YES;
  }
}];

But they are read only.
Unless you put underbar underbar – then it becomes read/write.

__block BOOL stoppedEarly = NO;
double stopValue = 53.5;
[aDictionary enumerateKeysAndObjectUsingBlock:^(id key, id value, BOOL *stop) {
    stoppedEarly = YES; // this is legal now
}];

What about objects messaged inside the block?

NSString *stopkey = [@"Enough uppercaseString];
...
if ([stopKey isEqualToString: key] ||

Any outside pointers are held onto strong by the block until the block goes off the heap.
So if the block needs it, it keeps it.

typedefs

To make our lives easier we sometimes user typedefs with blocks.

typedef double (^unary_operation_t)(double op);

_t is convention for telling us it’s a type (takes a double returns a double).

Now we can declare a variable of that type called square:

unary_operation_t square;
square = ^(double operand) { // value of square is a block
   return operand * operand;
}

Now we can use:

double sequareOfFive = square(5.0);

We could then use the unary_operation_t to define a method

@property (nonatomic, strong) NSMutableDictionary *unaryOperations;
typedef double (^unary_operation_t)(double op);
-(void) addUnaryOperation: (NSString *)op whichExecutesBlock:(unary_operation_t)opBlock {
   [self.unaryOperations setObject:opBlock forKey:op];
}

What this does is associate a block with an operation and store it in a dictionary.

Look at how beautifully these reads though:

addUnaryOperation (a string called op) whichExecutesBlock: unary_operation_t

Really nice syntax the way you can define variables right beside the variable declarations themselves.

Blocks are managed in iOS5 by ARC (so you don’t have to worry about memory management around these).

Then we could use this later on like:

-(double)performOperation:(NSString *)operation
{
   unary_operation_t unaryOp = [self.unaryOperations objectForKey:operation];
   if (unaryOp) {
      self.operand = unaryOp(self.operand);
   }
}

We don’t always typedef

When a block is an argument to a method and is used immediately, often there is no typedef. We just inline it.

-(void)enerateKeysAndObjectsUsingBlock:(void (^)(id key, id obj, BOOL *stop))block;

Here block is the local variable name.

Some shorthand allowed when defining a block

1. You do not have to declare the return type if it can be inferred.
2. If there are no args don’t need parentheses.

NSNumber *secret = [NSNumber numberWithDouble:42.0];
[brain addUnaryOperation:@”MoLtUaE” whichExecutesBlock:^(double operand) {
   return operand * [secret doubleValue];
}];

And

[UIView animateWithDuration:5.0 animations:^{
   view.opactity = 0.5;
}];

No args to this block. No need to say ^() { …}

Memory Cycles (bad thing)

What if you had a block that referred to itself?

@property (nonatomic, strong) NSArray *myBlocks;

[self.myBlocks addObject:^() {
   [self doSomething];
}];

The block here has a strong pointer to itself.
But self has a strong point to block (through it’s property!).

This is a serious problem.

Neither self non block can ever escape the heap now because they will both be pointing to each other.
Called a memory “cycle”.

There is a magic underbar underbar weak.
Says this variable is weak.

__weak Myclass *weakSelf = self;
[self.myBlocks addObject:^() {
   [weakSelf doSomething];
}];

Solves the problem because now the block only has a weak pointer to self.
Self still has a strong point to the block, but that’s OK.

When do we use blocks in iOS?

Enumeration
View animations
Sorting
Notification (when something happens execute this block)
Error handlers
Completion handlers

But mostly it’s for multithreading. Do this using GCD (Grand Central Dispatch).