Blocks, loops, and local variables

Consider the following code snippet:

for(/* some condition */) { int x = rand(); [array addObject:^(){ NSLog(@"%d", x); }] } for(void (^block)() in array) { block(); } 

Now I expect this piece of code to print all the values โ€‹โ€‹assigned to x in that for the loop; however, it seems that all the blocks have the same variable "x" (supposedly the last one).

Any idea why this is so, and how can I fix the code so that each block contains the variable "x", as it was when the block was defined?

+6
source share
1 answer

The documentation specifically states that this should not be done . The reason is that blocks are allocated on the stack, which means that they can go out of scope. For the same reason, you cannot access the variable x outside the first for loop, you should not use this block either. x went out of scope with the block itself and can contain any value.

To get around this, you can take a copy of the block as follows:

 for(/* some condition */) { int x = rand(); void(^logBlock)() = ^() { NSLog(@"%d", x); } [array addObject:[[logBlock copy] autorelease]]; } 

This moves the block to the heap and fixes your problem.

+7
source

Source: https://habr.com/ru/post/899197/


All Articles