IOS >> Blocks >> Change of values ​​of variables external to the block

I am familiar with the __block operator, which makes a variable "assignable" inside a block. But I see that when using some Objective-C functions that use Blocks as arguments in methods, some variables can be assigned even if they are not declared using this __block operator.

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 associated with 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 can I assign values ​​to the properties of a UIView instance?

I do not access the object and do not change it, like my mString.

I would expect the "center" property to behave like my myInt, since it is directly related to the C structure, and not to the pointer to the object.

I would expect 'backgroundColor' to behave like my imString, since it is a pointer to an object that is assigned by the new object, right?

I could not find a satisfactory explanation in the documentation ... I would appreciate it if anyone could provide it or contact me.

+7
variable-assignment ios objective-c block objective-c-blocks
source share
3 answers

This is the difference between purpose and use. Using a method call method. You are fully allowed to call methods on the instance ( [mString appendString:@" Block"]; //working ), but you cannot assign ( imString = @"Imutable Hello Block"; //error ) without marking variables to tell the compiler, that he should turn it on.

This code:

 self.animatedView.backgroundColor = [UIColor blueColor]; 

still not a destination, this is a call to a "hidden" method. Dot notation is never a destination; it is syntactic sugar for method calls. This actually means:

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

The difference between assigning local variables and variables within an object is the location in memory in which they are located. In principle, they will exist long enough to be useful. This is the difference between the data on the stack and the heap.

+8
source share

To allow a variable to be changed in a block, you use the _block repository type modifier - see " _ block Repository type ."

 __block NSString* imString = @"Imutable Hello"; 

Link apple doc

For the variables used in the block, the following rules apply:

  • Global variables are available, including static variables that exist in the covering lexical domain.
  • The parameters passed to the block are available (just like the parameters for the function). A stack of (non-static) variables local to the covering lexical domain are captured as constant variables.
  • Their values ​​are taken at the point of the expression block inside the program. In nested blocks, the value is captured from the nearest spanning area.

  • Variables local to the covering lexical region declared using the __block repository modifier are provided by reference and are therefore mutable.

  • Any changes are reflected in the covering lexical area, including any other blocks defined within the same covering lexical area. They are discussed in more detail in the __block Storage Type section.

  • Local variables declared in the lexical region of a block that behave like local variables in a function.

  • Each block call provides a new copy of this variable. These variables, in turn, can be used as constant or reference variables in blocks enclosed within a block.
+3
source share

In the first example, the block "captures" the variable self - a pointer to the stored object. You do not change yourself in your example when you write:

 self.someProperty = someValue; 
Self-esteem

still remains unchanged - that is, it still points to the same object.

You would change yourself, for example, if you write:

 self = nil; 
+2
source share

All Articles