iPhone Development

Just another iPhone Blog

Tag Archives: blocks syntax

Why I like Blocks?

In my last post here , I wrote about the syntactical difference between the Blocks and the C Funtion pointers. In this post I share my first hand experience on Blocks and how it changed my programming style and thinking, especially if you are not from Java / Javascript world.

 

In simple terms, Blocks are tiny independent code blocks that could be executed on its own. How did Blocks saved me? Lets take below code snippet as an example:

 

[imageDownloader downloadHUGEImage: ^(UIImage* newImage){

    [self createThumbNailForImage:(UIImage * newImage)];

}]

 

v/s

 

[imageDownloader setDownloadDelegate: self ];

[imageDownloader downloadHUGEImage];

..

..

.

 

– (void)imageDownloader:(BBImageDownloader*)downloader didDownloadImage:(UIImage*)image

{

    [self createThumbNailForImage:(UIImage * newImage)];

}

 

Advantage #1: It added more readability to my code:

Everyone would know what we are exactly doing after downloading an image, where as with delegate pattern, one has to jump to definition of the delegate methods, which sometimes resides in multiple files, by then you would lose the trace of the initial method.

 

Advantage #2: Eliminates Delegate Pattern

The same reason as above, With Blocks, you will no more have to spend your time in retain cycle which is more common mistake made by programmer when using delegate pattern in Objective-C, (although blocks do produce retain cycles, but they are easy to detect   )

 

 

Advantage #3: Save more context info variables.

Lets take an example of usage of beginAnimation: method on UIView in Pre-Block Era.

int state_before_animation = 0

[UIView beginAnimations:@” ” contextInfo:& state_before_animation]

 

..

 

..

 

– (void)animations:(NSString*)animation didFinish:(BOOL)finish contextInfo:(void*)contextInfo

{

    //do some\

int *state_before_animation = (int*)contextInfo

//change state depending upon state_before_animation

}

 

 

– During the execution time between start of animation  and completion of animation, we lose the scope of local variables that were available at the start. This made the necessity of carrying these variables in the form of contextInfo

 

– It increases the burden of maintaining the integrity of the contextInfo variable during this time, it travels between different modules and sometimes b/w the third party libraries. 

 

With blocks, it makes much more simpler to write:

 

int state_before_animation =0

[UIView animateWithDuration:0.9 beforeAnimation:^{

 

}

afterAnimation:^{

   //do something depending upon state_before_animation

}

];

 

 Isn’t it decreases your development time?

 

Happy Coding 🙂

Blocks Syntax and its Variants

This post is specifically to me. I am not sure why I am not able to remember this simple syntax of the passing blocks as parameter.

 

So here it is.. Its very similar to C function pointers

<return type> (* [<function pointer name>])( [parameter1, parameter2….])

The only difference is to replace * to ^.  <function pointer name> is name of the block, Lets call its as as <block name>.  if you are using this directly to pass a block as  a parameter to a method, then the <block name> is not needed.

 

For Example, You declare a method which accepts a block as a parameter like this:

-(void)performLongOperation:( void (^)(NSError *error, id result))completionBlock;


Variants of Creating and Defining a Block


a. Block definition as part of method invocation:

 

One would invoke the block within the performLongOperation method definition as:

NSError * error = nil;

id result = nil;

..

..

..

completionBlock(error, result );

The caller would look like:

  [self performLongOperation: ^(NSError *error, id result){

        //what you want to do after performLongOperation?

    }];

This is one of the way where the whole body of the block is written as part of method invocation.

 

 

b. Block as a variable OR a named Block:

 

If the above code snippet looks complicated (esp. if the callback is very lengthy) or if there is a need to separate the callback from the caller, then you can give a name to a block like this:

  void (^ myblock )(NSError *, id result)  = ^(NSError *error, id result){

        //what you want to do after performLongOperation?

    };

where myblock is the name of the block. The method invocation would look like:

    [self performLongOperation: myblock];


c. Block as a custom data type


In some cases, we might want to pass a different callback functions based on certain conditions and in order to do that we can create our own custom data type using typedef.

typedef void (^my_block_type)(NSError *, id );

and create a block variable of type my_block_type which accepts two parameters of type NSError and id and returns nothing.

my_block_type validate_long_operation_result = ^(NSError *error, id result){

        //validate result

    };

 

my_block_type divert_to_second_operation = ^(NSError *error, id result){

        //do second operation

    };

Caller would look like this:

[self performLongOperation: ( should_chose_second_operation ? divert_to_second_operation :  validate_long_operation_result)];

 

Click Me for More Info on Basics of Blocks


Happy Coding 🙂


%d bloggers like this: