Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

iOS >> Blocks >> Changing Values of Variables External to the Block

I'm familiar with the __block statement that makes the variable 'assignable' within a Block. But I see that when using some of Objective-C features that uses Blocks as Arguments in Methods, some variables are assignable, even if they are not declared with this __block statement.

Here are 2 codes for example:

[UIView animateWithDuration:2 animations:^
     {
         self.animatedView.backgroundColor = [UIColor blueColor];
         self.animatedView.center = CGPointMake(100, 100);
     }];

(animatedView is a simple UIView connected with an IBOutlet).

    int myInt = 10;
    NSMutableString* mString = [NSMutableString stringWithString:@"Mutable Hello"];
    NSString* imString = @"Imutable Hello";

    void (^myBlock)(void) = ^
    {
        [mString appendString:@" Block"]; //working
        imString = @"Imutable Hello Block"; //error
        myInt = 11; //error
    };

My question is: How come I can assign values to the UIView instance properties?

I'm not addressing an Object and changing it, like my mString.

I would expect the 'center' property to behave like my myInt, as it's a C struct accessed directly, and not a pointer to an object.

I would expect 'backgroundColor' to behave like my imString, as it's a pointer to an object which is assigned with a new object, isn't it?

I couldn't find a satisfying explanation in the documentation... I would appreciate if anyone can provide one, or address me to one.

like image 999
Ohad Regev Avatar asked Feb 10 '14 10:02

Ohad Regev


People also ask

What are IOS blocks?

Blocks are a language-level feature added to C, Objective-C and C++, which allow you to create distinct segments of code that can be passed around to methods or functions as if they were values. Blocks are Objective-C objects, which means they can be added to collections like NSArray or NSDictionary .

What does __ block do?

__block is a storage qualifier that can be used in two ways: Marks that a variable lives in a storage that is shared between the lexical scope of the original variable and any blocks declared within that scope. And clang will generate a struct to represent this variable, and use this struct by reference(not by value).

Which variables are accessible to all the blocks?

Global variables are accessible, including static variables that exist within the enclosing lexical scope. Parameters passed to the block are accessible (just like parameters to a function).

What is a block variable?

Block scoped variables: A block scoped variable means that the variable defined within a block will not be accessible from outside the block. A block can reside inside a function, and a block scoped variable will not be available outside the block even if the block is inside a function.


1 Answers

This is the difference between assignment and usage. Usage being method calls. You are entirely permitted to call methods on an instance ([mString appendString:@" Block"]; //working) but you can't assign (imString = @"Imutable Hello Block"; //error) without tagging the variables to tell the compiler that it should enable it.

This code:

self.animatedView.backgroundColor = [UIColor blueColor];

is still not really an assignment, it's a 'hidden' method call. Dot notation is never an assignment, it's syntactic sugar for method calls. It actually translates to:

[[self animatedView] setBackgroundColor:[UIColor blueColor]];

The difference between assigning to local variables and to variables inside an object is the location in memory that they reside at. Basically, will they exist for long enough to be useful. It's the difference between data on the stack and on the heap.

like image 102
Wain Avatar answered Nov 15 '22 15:11

Wain