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