Re: Storing a block in a CF/NSMutableDictionary?
Re: Storing a block in a CF/NSMutableDictionary?
- Subject: Re: Storing a block in a CF/NSMutableDictionary?
- From: Ken Thomases <email@hidden>
- Date: Sun, 10 Apr 2011 11:39:41 -0500
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 (email@hidden)
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:
This email sent to email@hidden