What does the "__block" keyword mean? What does the "__block" keyword mean? ios ios

What does the "__block" keyword mean?


It tells the compiler that any variable marked by it must be treated in a special way when it is used inside a block. Normally, variables and their contents that are also used in blocks are copied, thus any modification done to these variables don't show outside the block. When they are marked with __block, the modifications done inside the block are also visible outside of it.

For an example and more info, see The __block Storage Type in Apple's Blocks Programming Topics.

The important example is this one:

extern NSInteger CounterGlobal;static NSInteger CounterStatic;{    NSInteger localCounter = 42;    __block char localCharacter;    void (^aBlock)(void) = ^(void) {        ++CounterGlobal;        ++CounterStatic;        CounterGlobal = localCounter; // localCounter fixed at block creation        localCharacter = 'a'; // sets localCharacter in enclosing scope    };    ++localCounter; // unseen by the block    localCharacter = 'b';    aBlock(); // execute the block    // localCharacter now 'a'}

In this example, both localCounter and localCharacter are modified before the block is called. However, inside the block, only the modification to localCharacter would be visible, thanks to the __block keyword. Conversely, the block can modify localCharacter and this modification is visible outside of the block.


@bbum covers blocks in depth in a blog post and touches on the __block storage type.

__block is a distinct storage type

Just like static, auto, and volatile, __block is a storage type. It tells the compiler that the variable’s storage is to be managed differently.

...

However, for __block variables, the block does not retain. It is up to you to retain and release, as needed.
...

As for use cases you will find __block is sometimes used to avoid retain cycles since it does not retain the argument. A common example is using self.

//Now using myself inside a block will not //retain the value therefore breaking a//possible retain cycle.__block id myself = self;


Normally when you don't use __block, the block will copy(retain) the variable, so even if you modify the variable, the block has access to the old object.

NSString* str = @"hello";void (^theBlock)() = ^void() {    NSLog(@"%@", str);};str = @"how are you";theBlock(); //prints @"hello"

In these 2 cases you need __block:

1.If you want to modify the variable inside the block and expect it to be visible outside:

__block NSString* str = @"hello";void (^theBlock)() = ^void() {    str = @"how are you";};theBlock();NSLog(@"%@", str); //prints "how are you"

2.If you want to modify the variable after you have declared the block and you expect the block to see the change:

__block NSString* str = @"hello";void (^theBlock)() = ^void() {    NSLog(@"%@", str);};str = @"how are you";theBlock(); //prints "how are you"