I understand that the __block
storage type is needed on scalar variables for the block to see updates to them, but when is it needed on objects? I believe __weak
should be used when capturing a self reference to be used within the block, but I don't see when it would be necessary to actually use the __block
storage type for ordinary objects.

- 5,278
- 9
- 40
- 64
-
Also [what the difference between __weak and __block reference?](http://stackoverflow.com/questions/11773342/what-the-difference-between-weak-and-block-reference) – Dave FN Jul 24 '13 at 00:26
-
I'm specifically asking: when the `__block` storage type should be used on non-scalar, non-self object references when using ARC? If those other links answer that question I've missed it. – chinabuffet Jul 24 '13 at 00:30
-
@chinabuffet: There is no difference between how it works for scalar types and object pointer types. – newacct Jul 24 '13 at 21:16
2 Answers
__block
is needed for scalar variables if you want to change their value with code inside the block. Captured scalars appear as const
inside the block and therefore cannot be changed. If you have a pointer to an object, the same distinction applies--the captured pointer itself will be a const
pointer and therefore cannot be modified, but the object pointed to can be modified by code inside the block. If you want to change the object pointed to, then the pointer itself must change, and so the pointer must be declared with the __block
type. It is never necessary to declare the object itself as __block
, but only the pointer to the object, and only if the pointer must be changed.
If you have the right mental model, blocks aren't that confusing. It is important to know that blocks are initially allocated on the stack, and so vanish when the lexical scope is destroyed as the stack frame is popped. If you want the block to hang around past the lifetime of the lexical scope in which the block was created, move it to the heap using Block_copy()
or sending it a -copy
message. When a block is copied to the heap, all the captured const
variables go along, and any objects these const
variables point to are retained. When the block is removed from the heap, all objects pointed to by the const
variables are released.
__block
variables "under the hood" have an extra layer of indirection the compiler uses (and that you don't see) included in the block, so when the block is copied to the heap, so are the captured __block
variables, and the invisible pointers are adjusted to point to the new heap location of these __block
variables. This means the address of a __block
variable can change, so be careful if you use that address. You can also see that a __block
variable lives 'outside' the block in some sense, so these variables can be read and modified from code external to the block.
I've been brief, but you can find better explanations here, listed in increasing complexity:
http://ios-blog.co.uk/tutorials/programming-with-blocks-an-overview/
http://www.cocoawithlove.com/2009/10/how-blocks-are-implemented-and.html
http://www.mikeash.com/pyblog/friday-qa-2011-06-03-objective-c-blocks-vs-c0x-lambdas-fight.html

- 8,582
- 1
- 21
- 27
-
So if the block is passed as a reference somewhere, does whatever is receiving that block as a parameter need to immediately copy the block in order to use it in the future? – chinabuffet Jul 24 '13 at 12:27
-
If the block reference can outlive the lexical scope (stack frame) in which the block was defined, it must be copied to move the block object to the heap. I'd think it would be safer to do the copy when creating the block than to have these copies occurring at places remote from the creation. – Fred Jul 25 '13 at 03:48
-
They are used for function level variables. These are mutable within the block (and the enclosing scope) and are preserved if any referencing block is copied to the heap. Variables local to the enclosing lexical scope declared with the __block
storage modifier are provided by reference and so are mutable. Any changes are reflected in the enclosing lexical scope, including any other blocks defined within the same enclosing lexical scope.
__block
variables live in storage that is shared between the lexical scope of the variable and all blocks and block copies declared or created within the variable’s lexical scope. Thus, the storage will survive the destruction of the stack frame if any copies of the blocks declared within the frame survive beyond the end of the frame (for example, by being enqueued somewhere for later execution). So use them when you need to modify the object within a block or when you will need the object after the destruction of the stack frame.

- 8,568
- 12
- 50
- 85