Blocks in Objective-C allows you to store the chunks of code in variables. Blocks can be assigned to a variable , passed to functions, and generally treated like any other value. Also the blocks can be called as the function, and they capture the state of the things as they were when the block was created.

A simple block would look something like this :

int i = 5;
void (^someCode)() = ^{
NSLog(@"The value of i is %i", i);
};

We can invoke the above block like a function :

someCode();  //This prints  “The value of i is 5”

Here we see that the value of the variable ‘i‘ was captured during the creation of the block , hence it its value is 5 when used within the block. Thus when a variable outside a block is referenced within that block, the value of that variable at the moment of the block’s creation is captured and is available for the block’s code to use.

Blocks allow you to defer the execution of something until you need it to actually happen. This makes them very useful in the context of animations (“when the animation’s done, do this thing”), for networking (“when the download’s done, do something else”), or in general user interface manipulation (“when I return from this new screen, do some work”). They also allow you to keep related pieces of code close together. For eg:- using Blocks we can avoid writing a method to filter the array elements having prefix “Apple” as below.

// Filter an array of strings down to only strings that begin with the word
// "Apple"
NSPredicate* filterPredicate = [NSPredicate predicateWithBlock:^(id anObject) {
NSString* theString = anObject;
return [theString hasPrefix:@"Apple"];
}];
NSArray* filteredArray = [someArray filteredArrayWithPredicate:filterPredicate];

 Blocks Syntax

[Return Type] (^ [Variable Name]) ([Parameters]);

With reference to the above syntax we can define the block variable as shown:

  • A simple block which returns no value and takes no parameters will be defined in the following ways
void(^myBlockVariable)(void);      
void(^myBlockVariable)();    //Since the block takes no parameters
  •  A block block which takes input parameters will be defined by adding the parameters in the paranthesis at the end –
void(^myBlockVariable)(BOOL booleanParameter, NSString* objectParameter);

Once a block variable has been declared, it must have a block assigned to it before it can be called.

void(^myBlockVariable)(BOOL parameter);   //Declaration of the block variable
myBlockVariable = ^(BOOL parameter) {    // Assigning Block to the block variable   
// Code goes here.
};
                               
                                         ---OR---
void(^myBlockVariable)() = ^{ //Declaration and initialization of a block variable 
// Code goes here.                  //This block takes no parameters
};

Once we have defined the block it can be called as a we invoke the function like : myBlockVariable();

Using Blocks as parameter in Methods

Since the block in objective C is treated as any other value and assigned to a variable ,it can be passed as the parameter to a function. This is a key feature of the block ,since it allows the caller of the methods to provide the code at the moment they call the method.

The method accepting the block as a parameter can be declared as below:

- (void) someMethod:(void(^)(BOOL aParameter)) handler;

The implementation of this method would be:

- (void) someMethod:(void(^)(BOOL aParameter)) handler {
// Call the passed-in block:
handler(YES);
}                                        

We can call the above method like this

[anObject someMethod:^(BOOL aParameter) {
// The called method will call this method
}];

We can simplify the deceleration of the block variable by defining the block type , this reduces the amount of typing the code to declare a block variable and using it. Also it makes sure that all the block we use are of the same type.

// somewhere in your source code, outside of a function or method:
typedef void(^ABlockType)(BOOL aParameter);

// and later, in a function:
ABlockType myBlock = ^(BOOL aParameter) {
// do some work
};

We can use the above declared block as the method parameter as shown here:

- (void) someMethod:(ABlockType)handler; //This looks much tidier...!

Be Careful when using blocks

When a block is created, it is stored on the stack memory. So when we create a block, store it in a instance variable of the method , and then if we return from this method the block is removed from the memory but the instance variable still points to where it was. Thus on calling this block now would crash as the block no longer exists. This problem can be solved by copying the block to the heap , and making it to be in the memory as long as needed.

// myBlockProperty is a property of this class that can store the block.
void(^myBlockVariable)() = ^{
// code goes here
};
self.myBlockProperty = myBlockVariable; // INCORRECT! The block
// won't exist after this function returns, and calling it will crash.
self.myBlockProperty = [myBlockVariable copy]; // SAFE. The
// block will be copied and stored on the heap, and stick around.

Modifying the Local variables from within the block

Since the block captures the value of the variables that was during the creation of the block. In order to modify the value of this variable from within the block, we must declare the variable marked with the __block keyword.

__block int i = 0;                    //Declaring the variable with __block keyword
void(^myBlock)() = ^{                 // A simple block which modify the value of 'i'
i = 4;
};
myBlock();
NSLog(@"i is now %i", i);             // will print "i is now 4"
References:

Books: Learning Cocoa with Objective-C ,By -Jon Manning, Paris Buttfield-Addison, and Tim Nugent.

To know more: