On Apr 10, 2011, at 9:49 AM, Fritz Anderson wrote:

> On 8 Apr 2011, at 7:51 PM, Kyle Sluder wrote:
> 
>> As explained in the Blocks Programming Guide, you should not allow
>> blocks that reference stack storage to escape that scope. See
>> "Patterns to Avoid":
>> http://developer.apple.com/library/ios/#documentation/cocoa/Conceptual/Blocks/Articles/bxUsing.html

The above link does not say "you should not allow blocks that reference stack 
storage to escape that scope" or anything like that.  It explains that a block 
literal expression -- the block itself, not anything it references -- is only 
valid within its scope, unless copied.  The problem in those examples is that 
references to blocks survive beyond the lifetime of the blocks themselves.


> I am grateful you called this to my attention, as I had been thinking that 
> blocks were closures, in which referencing (but not, usefully, changing) 
> stack-local variables would work.

Blocks are closures and referencing stack-local variables does work.  For 
non-__block variables, the block has a const copy of the value, just as though 
it were passed by value into a function.

> I'd been thrown by the existence of the __block attribute, which permits 
> referencing a stack-local variable as an lvalue. I had reasoned that if a 
> __block variable _is_ obviously a reference to that memory, a non-__block 
> variable (whose value does _not_ propagate to the stack variable when a block 
> changes it) obviously _couldn't_ be a reference.

You had been correct.  Kyle just confused you.


> One of the examples is:
> 
> void dontDoThis() {
>    void (^blockArray[3])(void);  // an array of 3 block references
> 
>    for (int i = 0; i < 3; ++i) {
>        blockArray[i] = ^{ printf("hello, %d\n", i); };
>        // WRONG: The block literal scope is the "for" loop
>    }
> }
> 
> ... which would be useful, and a perfectly sensible thing to want to do. I'd 
> hope the block literal would copy the stack context to the block structure, 
> cutting the block free of its initialization context.

It does.  The problem in this example is simply that the block itself does not 
survive the specific pass through the "for" loop.  If the code above had copied 
the block (with a corresponding release, later), all would be fine.


I should say that there is a sense in which "you should not allow blocks that 
reference stack storage to escape that scope": if a block ends up holding a 
_pointer_ to a stack-local variable.  Then, of course, the block has a copy of 
the pointer, but not the pointed-to storage, so the pointer is a dangling 
pointer once control leaves the local scope.

Regards,
Ken

_______________________________________________

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Reply via email to