Blocks in Objective-C

Blocks in Objective-C

Quick overview

Blocks are the closure pattern implementation in Objective-C. Blocks are objects containing code like a method but blocks are standalone objects (not belonging to a specific class/instance) encapsulating and capturing the code and variables enclosed in the beginning and closing brackets.

You declare a block type or variable this way:
returnType (^blockName)(paramType, paramType)

Assign a block to this variable:
    ^ returnType (paramType paramName, paramType paramName) {
… code …
}

Block as a parameter:
(returnValue (^)(paramType, paramType))blockName

Call with a block as parameter:
^ returnType (paramType paramName, paramType paramName) {
… code …
}

Some example

You declare a block variable the following way:

// a block which takes a string and and int as parameter and returns a string
NSString* (^simpleBlockVariable)(NSString*, int) = ^ NSString* (NSString* stringParam, int intParam) {
    return [NSString stringWithFormat:@"stringParam %@, intParam: %d", stringParam, intParam];
};

// you can call it a the following way
NSString* stringResult = simpleBlockVariable(@"Hello", 1);

You can assign a new block to the same variable; you can also avoid the declaration of the return value since the compiler can find it out:

simpleBlockVariable = ^ (NSString* stringParam, int intParam) {
    return [NSString stringWithFormat:@"second version: stringParam %@, intParam: %d", stringParam, intParam];
}

Even you can avoid the parameter declaration so you get the simplest form of a block:

void (^simplestBlockVariable)() = ^ {
    NSLog(@"simplest block called");
};
 
// you call it like this   
simplestBlockVariable();

 

Passing blocks as parameters the syntax change a bit

// a block with two parameters: a string and a block which takes to parameters (string and int) and returns a string
NSString*(^blockVariableWithBlockParameter)(NSString*, NSString*(^)(NSString* , int )) = ^ NSString* (NSString* theString, NSString*(^completion)(NSString* , int )) {
    NSString* aNewString = [NSString stringWithFormat:@"Incoming string: %@", theString];
    NSString* resultString = completion(aNewString, 10);
    return resultString;
};

// you call it the following way    
NSString* theResult = blockVariableWithBlockParameter(@"Hello", ^ NSString* (NSString* stringParam, int intParam) {
    NSString* resultString = [NSString stringWithFormat:@"string from the completion: stringParam: %@, intParam: %d", stringParam, intParam];
    return resultString;
});

// Value of theResult: string from the completion: stringParam: Incoming string: Hello, intParam: 10