What does the "__block" keyword mean?
@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;
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.