Monday, 15 June 2015

Blocks in objective c

Blocks in Objective C

If you have not learn my previous tutorial then please read it from here: learn objective c



Blocks in IOS is added after 4.0 version including GCD (it is used in multithreaded programming i will discuss it lator).

If you have familiar with closures called in other languages then it is easy to used blocks for you.

Blocks as name suggest is sequence of statements. You can say it is block of code. These are written in {} braces.


In general Blocks are used when there are following cases occurs:

1.) Notification (when you are busy on work and notifications comes from any of your application and ask for what block of code to be executed.)

2.)Completion Handler(Blocks are widely used here: When main thread is running and background thread are also running behind after completion of that thread what block is to be executed.)

Do not be scare about thread i will explain lator about it.

3.) Enumeration.


Blocks are also used when calling a method with block of code, blocks are also
smarter to local variables used in function and referenced objects called for method.


For getting values you can use blocks in NSArray and NSDictionary if you have not  read it Click Here:NSArray in Objective C




Syntax to declare block

Caret symbol is used to declare block in objective c.

^{
NSLog(@"It is Programming Language.")
}

Above declarations is valid if there is no return type and arguement for block.

You can also used variable to trace all your block code.

return type (^ variablename)(arguements)
{
//your block code is here.
}


When you declared and assign a block then you can call that block by simple C programming language function calling.


variablename();


Example:


void(^studentDetail)(NSString *Studentid,NSString *firstName)
{
NSlog(@"The student detail is here: \n %@ \n %@",Studentid,firstName)
}



// call from here 

studentdetail(@"101",@"abc");

And the result will be printed.


Ok do not be confused with above example i just use simple addition of two numbers.

int (^add)(int a,int b)
{
return a*b;
}

int i=add(1,2);
NSLog(@"the sum of two numbers are:%d",i);


if you declare and assigning the block simultaneously then you need not to write the parameter name.

int i=void(^add)(int,int){
a*b;
}

this expression can also work.

Now go to why blocks are smarter in local variable.Lets go again Student example.
-(void)printDetail
{
int studentid=101;

void(^studentDetail)(NSString *studentName)
{
NSlog(@"The student detail is here: \n %@ \n %@",Studentid,firstName)
}
}

Above declaration is true. but it will print Studentid=101 for each student.

-(void)printDetail
{
int Studentid=101;

void(^studentDetail)(NSString *Studentid,NSString *studentName)
{
NSlog(@"The student detail is here: \n %@ \n %@",Studentid,firstName)
}

}
But now compiler generate error due to the read only capability of variable or property.

But do not be unhappy you can change the value of it by using _block keyword in front of during declaration of local variable.

How read only property changing?

When in block assigning the local variable then a copy of its generated from heap and after the successfull execution of block the value is added into heap at same index.

-(void)printDetail
{
_block int studentid=101;

void(^studentDetail)(NSString *studentName)
{
NSlog(@"The student detail is here: \n %@ \n %@",Studentid,firstName)
}
}

What happen if you call from object inside a block?

when you call a object inside a block the object will point to strong until the block is not fully executed.

{
// block code

[self method];

}


here self is point to strong reference.

Example: I have pass block as method argument. 




In Student.h

@interface Student : NSObject
@property(strong,nonatomic)NSString *StudentName;
-(void)printDetail:(NSString *)StudentName block:(void (^)(NSString *st))block;


In Student.m


@implementation Student
@synthesize StudentName=_StudentName;
-(void)printDetail:(NSString *)StudentName block:(void (^)(NSString *st))block
{
    NSString *st=StudentName;
    block(st);
}

In main section 



Student *student1=[[Student alloc]init];
        [student1 printDetail:@"abc" block:^(NSString *st){
            NSLog(@"The name of Student is:%@",st);
        }];


Output is shown here:







Source Code is available : Download Here

I hope you like my tutorial. If you have any query you can mail me or comment here.

My next tutorial will be Memory Management in IOS

No comments:

Post a Comment