A quote from Concurrency Programming Guide refers to variables that are created inside a function or method. The variables created inside them are created on the stack , which holds them until the function is called. In other words, when a function returns, its stack stack is destroyed along with the variables.
Objects in Objective-c are created on the heap so that they can live after the function returns, however when creating a string, for example:
MyClass *object = [[MyClass alloc] init];
You create an object to be placed in the heap, but you also create an object variable that contains a pointer to your object on the heap. This variable is placed on the frame stack of the current method / function and will be deleted after it returns. Your object, if you do not release it, will not be deleted, even if the function has ended.
This is why it blocks the variables of the parent variable of the parent referenced by the internal blocks. They are copied to block private memory, because they can be destroyed at the end of a function call, and, as you know, a block can be used after that. To do this, you need to use the __block specifier to tell the block that it does not copy the variable from the stack and does not use it directly. Since these variables can be destroyed when the function returns, the Concurrency Programming Guide indicates that in this case only synchronous sending should be used, since it will ensure that the block will be executed before the function returns. EDIT: As Martin R correctly pointed out that __block variables __block not always used directly from the stack. As stated in this documentation , they are treated as pointers, and their address can be changed from the stack when copying a block (for example, when sending). The copied variables are placed in storage, which is divided between the blocks and the function, in order to extend the variable's lifetime. I think the reason it is argued that local variables should be used with dispatch_sync is because environment variables other than ARC are not saved * , thereby creating the risk of using a freed object. For the same reason, I think you are not using __block in front of static and instance variables.
Variables that instance variables or static variables do not live on the stack of any function, so they are not copied by the block, and you do not need the __block specifier. A static variable will work as long as the program starts, but the instance variable is destroyed when the object that holds this variable is destroyed. Therefore, blocks have a different function - all objects referenced inside the block will be stored for the lifetime of the block to ensure that the object will not be released unexpectedly.