On Apr 14, 2011, at 9:19 AM, Jonathan Taylor wrote:

> Hi WT,
> 
>>> If I understand you correctly, what you're saying about your variable 
>>> "__block SomeObjType foo" is not true. Regardless of the __block qualifier, 
>>> foo is effectively a stack-based variable, so two simultaneously-executing 
>>> threads have their own independent instance of that variable. There can be 
>>> no "cross-talk" between the variables in separate threads - all you are 
>>> doing is enabling the block that a given thread executes to have access to 
>>> that specific thread's stack variable.
>> 
>> I'm afraid you're incorrect there. According to the documentation (or, more 
>> precisely, my understanding of the documentation), a variable qualified with 
>> __block starts in the stack but is moved to the heap, precisely because it's 
>> shared by all blocks capturing it and by all function scopes where it's 
>> declared. Therefore, I do not believe "two simultaneously-executing threads 
>> have their own independent instance of that variable" to be true.
> 
> I tested this out before replying as I wasn't 100% certain. It may be that we 
> have misunderstood each other somehow, but the following code (in a clean new 
> project) was what I used to confirm to myself that two concurrently-executing 
> threads have independent instances of the variable:
> http://www.dur.ac.uk/j.m.taylor/block_test_code.m

On this point Jonathan is correct. What __block does is ensure that a declared 
variable has the ability to survive its stack frame, not that a variable of 
that name is shared with all invocations of that stack frame. If you want a 
variable that will be shared with all instances of that stack frame, you want 
the "static" qualifier.

>>> However I don't think you should need to do this anyway. I would change 
>>> your code to something like this:
>>> 
>>> - (SomeObjType) foo
>>> {
>>> dispatch_sync(queue,
>>> ^{
>>>     // Code in this block ensures bah is valid
>>>     if (nil == bah)
>>>     {
>>>         // Code to compute and store bah goes here
>>>     }
>>> });
>>> 
>>> return bah;
>>> }


Fundamentally however, this will not work. If you want to do lazy 
initialization of a variable with thread safety then you should use 
dispatch_once() to initialize the variable. This is also not something you can 
do with a __block or static variable (unless you want all instances to have the 
same value, which seems to be against the way you've declared the method). 
Basically you need to do this:

- (SomeObjectType) foo
{
        dispatch_once(&ivar_predicate, ^ { ivar_value = /* initialization */ });
        return ivar_value;
}
--
David Duncan

_______________________________________________

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