Changing Enclosing Scope
Blocks can also change their enclosing scope. Say you want to count the number of badgers found inside of the list of words. You want the flexibility of providing subString to the block, but you also want a way for multiple invocations of the block to calculate a value and let the enclosing scope know about that value. A return value from the block will not work here because the badger count is calculated across an arbitrary number of block invocations. You cannot use a captured variable because they are const.
__block, with two leading underscores, is a new compiler keyword introduced to indicate that an enclosing scope variable can be modified from inside of the block.
Here is an enumeration that counts the number of badgers:
NSString *subString = @"badger"; __block int count = 0; [array enumerateObjectsUsingBlock: ^(id object, NSUInteger index, BOOL *stop) { NSRange match = [object rangeOfString: subString]; if (match.location != NSNotFound) { count++; } }]; NSLog (@"found %d %@s", count, subString);
prints
found 2 badgers
The block will be invoked once for each object in the array executing the code from top to bottom. count is incremented if object contains subString. Because count is __block scoped, a common piece of memory is having its value changed. __block says "Hey, this variable can be changed inside of a block." Of course, global variables and function-scoped static variables can be changed inside of a block without needing the __block qualifier.
Captured objects are not retained with __block. There are no thread safety guarantees with __block variables, so if your block could be executed on multiple threads simultaneously, you will need to take proper thread safety precautions.
Programmers familiar with other languages may recognize these block features under different names: Lambdas, closures, anonymous functions, as well as "blocks" in languages like Ruby and Smalltalk.