Note that there are some explanatory texts on larger screens.

plurals
  1. POShould a block literal retain referenced heap-allocated blocks
    primarykey
    data
    text
    <p>Consider the following code:</p> <pre><code>// t included so block1 is a stack block. See [1] below int t = 1; SimpleBlock block1 = ^{ NSLog(@"block1, %d", t); }; // copy block1 to the heap SimpleBlock block1_copied = [block1 copy]; // block2 is allocated on the stack, and refers to // block1 on the stack and block1_copied on the heap SimpleBlock block2 = ^{ NSLog(@"block2"); block1_copied(); block1(); }; [block1_copied release]; // When the next line of code is executed, block2_copied is // allocated at the same memory address on on the heap as // block1_copied, indicating that block1_copied has been // deallocated. Why didn't block2 retain block1_copied? SimpleBlock block2_copied = [block2 copy]; block2_copied(); [block2_copied release]; </code></pre> <p>Where, for completeness, SimpleBlock is defined by:</p> <pre><code>typedef void (^SimpleBlock)(void); </code></pre> <p>As indicated by the comment in the code, my tests (using both GCC 4.2 and LLVM 2.0) show that block1_copied is deallocated by the time [block2 copy] is called, yet according to the documentation that I have read [1,3], blocks are objective-c objects and blocks retain objective-c objects to which they refer [2] (in the non-instance variable case).</p> <p>Additionally, note that when block2 is copied, its reference to block1 is also changed to a reference to a new copy of block1 (which is different than block1_copied), as expected, since blocks copy any blocks to which they refer [2].</p> <p>So, what's going on here?</p> <p>A) If blocks retain objective-c objects to which they refer and blocks are objective-c objects, why is block1_copied deallocated before block2 goes out of scope?</p> <p>B) If blocks copy blocks to which they refer, and if sending -(id)copy to a heap-allocated block actually just increments its retain count, why is block1_copied deallocated before block2 goes out of scope?</p> <p>C) If this is the expected behavior, where is the documentation that explains it?</p> <p>[1] <a href="http://cocoawithlove.com/2009/10/how-blocks-are-implemented-and.html">http://cocoawithlove.com/2009/10/how-blocks-are-implemented-and.html</a><br> [2] <a href="http://developer.apple.com/library/ios/#documentation/cocoa/Conceptual/Blocks/Articles/bxVariables.html">http://developer.apple.com/library/ios/#documentation/cocoa/Conceptual/Blocks/Articles/bxVariables.html</a><br> [3] <a href="http://clang.llvm.org/docs/BlockLanguageSpec.txt">http://clang.llvm.org/docs/BlockLanguageSpec.txt</a> </p> <p>Footnote: In my tests, the result of running this code is an infinitely recursive call to block2_copied(), since block1_copied() had the same memory address as block2_copied.</p>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload