Monday, January 25, 2016

Objective C __block access specifier in Blocks

Using Blocks we can write inline functions. They make programming readable and handy, Where we can call for something and write the sequence of actions need to be performed after getting the response there itself.

Arrays can be looped using blocks. UIAnimation can be done using blocks. Ever since Objective C is having this Block concept, programming became more easy and handy.


                         



In this post let's see a scenario where I need to access an outside variable in the Block. Let's see whether we can access it directly or do we need to do something for that.

Let's say I have an array of elements, which are fruits.


   
NSArray *fruits = [NSArray alloc] initWithObjects:@"Orange",@"Banana",@"Apple",nil];


I have an input text box, where user can enter their own fruit name. I need to add that value to my fruit array. Before adding that, It is mandatory to check whether that fruit is already there in the array or not.
To do that I am iterating through the array using enumerateObjectsUsingBlock method.

I have taken a BOOL variable to set the existence of the fruit in the array.



  
 BOOL fruitISAlreadyThere = NO;
    
    [fruits enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {

        NSString *fruit = (NSString *)obj;

        if ([fruit isEqualToString:thisNote.notesID]) {

            fruitISAlreadyThere = YES;  //throws compile time error
            *stop = YES;
        }

    }];

    if (!fruitISAlreadyThere) {  
          // Add it to the array
    }

    
If I directly try to access the 'fruitISAlreadyThere' variable in the block as shown in the above code, It throws the below compile time error.


'Variable is not assignable (missing __block type specifier)'

    
It means, You can't directly assign an out side variable inside the block. To do this we need to add __block specifier as prefix to that variable. In this case It is as shown below.



   
__block BOOL fruitISAlreadyThere = NO;


Now, build your application, It won't throw that compilation error. You are now able to assign values which are initialized outside of the block.

Hope this post is useful. Feel free to comment incase of any queries.