When you use an instance variable, the compiler turns what you see as the ivar name into self->iVar
, and that's what the block uses. You can even do this in your code - try accessing something with self->
prepended.
EDIT: So in the first case, the block captures self
, because it needs it to access instanceVariable
, as in self-> instanceVariable
. Thus, it will use whatever the value is when the block finally executes. Since self
is an object, it gets retained.
In the second case, a temporary variable (object or not) is assigned the current value of self-> instanceVariable
, whatever it is at that moment. When the block captures localVariable
, it retains the object, and just after the dispatch_async call, ARC releases localVariable
, so the block now is the only thing retaining localVariable
. From then on, the class can change the instance variable and it will have no affect on whatever the block captured (one exception - if the object is a mutable object, then the block will use whatever the contents are when it runs - the reason to NOT to use mutable objects in this situation, but to use a non-mutable copy.