Using Blocks in iOS

Reading Time: 8  min

Introduction:

Blocks are similar to standard C function having additional support for variable bindings to stack memory and heap memory. Due to this additional support block can maintain a set of state that it can use to impact behavior when executed. Blocks are available with GCC and Clang compiler.   They can be used with OS X v10.6 and later, and iOS 4.0 and later.

 Definition:

Block is an inline anonymous function that let you encapsulate chunks of code. You can pass this chunk around like any other objects/variables. Block is denoted by carat (^) symbol.

Declaration:

return type(^block name)(arguments)

 

 

eg.

double (^add) (float);

Implementation:

float constantNumber=12;

double (^add) (float); //add is the name of the block which takes float as an argument

add=^(float i)

{

return constantNumber+i   //block body

};

It is also possible to combine the declaration and implementation of block:

double(^add)(float)=^(float i)

{

return constantNumber+i

};

Note: Make sure to close the blocks with semicolon.

 

Calling a Block:

To call a block is as same as to call a function.

blockname(arguments);

eg.   float result= add(12);

__block specifier:

 In the above code if you want to change the value of constantNumber you will do something like this

float constantNumber=12;

double(^add)(float)=^(float i)

{

constantNumber=20;

return constantNumber+i

};

On running the above code compiler will generate the error “Variable is not assignable(__block specifier is missing)”. This is because blocks   capture the local variables in its scope and create its own readonly copy of local variables on the stack which is called closure.

Here the compiler is telling us that we need to use __block specifier. Doing so will make the compiler arrange for it to be placed on the heap so that it can be used by all blocks, and will no longer be declared const inside the block itself.

Thus we can get rid of this error by changing the above code to:

 __block float constantNumber=12;

double(^add)(float)=^(float i)

{

constantNumber=20;

return constantNumber+i

};

From Apple

Blocks are a useful alternative to traditional callback functions for two main reasons:

  1. They allow you to write code at the point of invocation that is executed later in the context of the method implementation.

Blocks are thus often parameters of framework methods.

  1. They allow access to local variables.

The delegate methods are separate methods than the caller. If delegate methods require to access local variables of caller method, its not possible. Those variables need to be created as class level without any specific use case. Using block specifiers, one can simply access local variables directly.

Thus blocks are good for the below specified reasons:

  • Completion handlers
    • Notification handlers
    • Error handlers
    • Enumeration
    • View animation and transitions
    • Sorting

Example

Lets take the example of asynchronous request.

Here you get the response in its respective delegate methods

So your code becomes much scattered at different places. How about you get the response at the very next line of the callback function??

Blocks is the answer.

Lets take one class named ViewController from where you can call the web service.

CallWS *obj=[[CallWS alloc] init];

[obj callWS:@”http://www.google.com” completion:^(NSError *error, NSData *result)

{

if(nil == error)

{

NSLog(@”result ==%@”,[result description]);

}

}];

CallWS is the other class that contains the delegate methods of our NSURLConnectionDelegate and that also assigns the block on response.

CallWS.h

@interface CallWS : NSObject

{

NSMutableData* responseData;

}

@property (nonatomic, copy) void (^completeGettingListUpdate)(NSError *error, NSData *result);

CallWS.m

-(void)callWS:(NSString *) serviceString completion:(void (^)(NSError *, NSData *))completion

{

//Save the block variable as a class member

self.completeGettingListUpdate=completion;

NSURL *serviceURL = [NSURL URLWithString:serviceString];

NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:serviceURL];

NSURLConnection *serviceConnection = [NSURLConnection connectionWithRequest:request delegate:self];

if (serviceConnection != nil)

{

responseData = [[NSMutableData alloc] init];

}

}

In the above code, a block variable is received as a parameter. Save this variable for calling a block when communication will get completed.

Rest of the code will create an URL object and URLRequest Object. Create the connection with URLRequest object. When the communication will start, any/all of below delegate method will get called.

– (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response

{

[responseData setLength:0];

}

– (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data

{

[responseData appendData:data];

}

– (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error

{

NSLog(@”Connection failed with error:%@”,[error localizedDescription]);

completeGettingListUpdate(error,nil);

}

– (void)connectionDidFinishLoading:(NSURLConnection *)connection

{

NSLog(@”Connection finished communication:%@”,[error localizedDescription]);

completeGettingListUpdate(nil,responseData);

}

Here at the end of the communication and at the time of error generation, block is called. So the ViewController class which has generated the call will work like synchronous method call. However the communication is handled in asynchronous mode.

This is the power of block!!!

For more details visit the Apple Link.

 

 

Stay Updated
Please enable JavaScript in your browser to complete this form.
LinkedIn
Share
Copy link
URL has been copied successfully!

Other stories you may enjoy...

One Year In: Technology Success Stories from the Pandemic

This time last year, US companies were forced to face a new and unsettling reality: business as usual was no longer an option. I wrote then about how businesses could shift their...

How to Work with Your Remote Development Team

Working with remote teams to develop and release new products has become the norm for almost all aspects of software development.  Nowhere is that more true than in the mobile...

Think You Know Your App Dev Needs? Think Again.

The pace of change in mobile app development has been mind-blowing. Here at Apexon, we’ve been working on mobile apps since their inception. With every project we learn...