I was reading through the documentation on __block variables, and thinking about the cases where I use __block. To me, it seems like I need it in two cases:
On the surface it doesn't seem like these two things are related. I consider the fact that __block variables not being retained as more of a trick I need to remember for the specific use case of avoiding retain cycles.
I'm wondering, is there a more important, architectural reason why they must not be retained? I would think some other keyword to indicate this might be more clear, as to not mix up the two features listed above.
update -
I should mention this is code that does not use ARC. I now see that __block variables are in fact retained in ARC.
__block
variables are not retained if you use Manual Reference Counting. The reason can be found here: http://www.mikeash.com/pyblog/friday-qa-2009-08-14-practical-blocks.html:
A simple workaround to this lies in the fact that
__block
variables are not retained. This is because such variables are mutable, and automatic memory management of them would require each mutation to generate memory management code behind the scenes. This was seen as too intrusive and difficult to get right, especially since the same block may be executing from multiple threads simultaneously.
and also here: http://lists.apple.com/archives/objc-language/2009/Dec/msg00100.html
There is no way to properly and efficiently manage the retain counts upon re-assignment of the value within the variable.
(I could not find an "official" reference in the Apple documentation.)
As documented in the "Transitioning to ARC Release Notes", this behavior changed with ARC:
In manual reference counting mode,
__block id x;
has the effect of not retainingx
. In ARC mode,__block id x;
defaults to retaining x (just like all other values). To get the manual reference counting mode behavior under ARC, you could use__unsafe_unretained __block id x;
. As the name __unsafe_unretained implies, however, having a non-retained variable is dangerous (because it can dangle) and is therefore discouraged. Two better options are to either use__weak
(if you don’t need to support iOS 4 or OS X v10.6), or set the__block
value tonil
to break the retain cycle.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With