On Apr 14, 2011, at 7:44 PM, David Duncan wrote:

> On Apr 14, 2011, at 10:26 AM, WT wrote:
> 
>> On Apr 14, 2011, at 2:09 PM, David Duncan wrote:
>> 
>>> On Apr 14, 2011, at 10:02 AM, WT wrote:
>>> 
>>>> I looked at dispatch_once() at one point, but I'm still confused by how it 
>>>> works.
>>> 
>>> dispatch_once uses a predicate (just a flag) to determine if it should run 
>>> the block or not. If that flag is false, then it sets the flag to true and 
>>> executes the block. If the flag is true, it does nothing. What makes 
>>> dispatch_once useful over a simple if statement is that it ensures that if 
>>> you execute dispatch_once concurrently from multiple threads that flag gets 
>>> updated exactly once, and the block gets called exactly once.
>> 
>> Thanks for explaining it, David. The bit that was throwing me off is the 
>> predicate part. I understand now that all I need is to declare a static 
>> variable of the appropriate type and pass a pointer to it to dispatch_once().
> 
> The lifetime of the predicate needs to match that of the initialization done 
> by the block. If the block's initialization is done for an instance variable, 
> then the predicate should also be an instance variable. If the initialization 
> is for a global, the predicate should also be a global.

So I just want to confirm this... Are you saying that one can do something like:

@interface MyObject
{
    dispatch_once_t initilizeComputedResource;
    ComputedResource* theResource;
}

- (ComputedResource*) resource;
@end

@implementation MyObject
- (ComputedResource*) resource
{
    dispatch_once(&initilizeComputedResource, ^{
        theResource = [self doSomeBigComputation];
    });
    return theResource;
}
@end

and later I can call 

{
    MyObject* anObject = [[MyObject alloc]init];
    ComputedResource* r = [anObject resource];
    [r doSomething];
}

and its legal? (I have GC switched on)

Looking at  
http://developer.apple.com/library/ios/documentation/Performance/Reference/GCD_libdispatch_Ref/Reference/reference.html#//apple_ref/c/func/dispatch_once
and the bit where it says:

 "The predicate must point to a variable stored in global or static scope. The 
result of using a predicate with automatic or dynamic storage is undefined."

Seemed to me to indicate that it wasn't valid to have the kind of code I have 
above... I would like to use the code I have above so I can ensure something is 
run *once* for a given object. (Otherwise of course I just fall back on 
@synchronized but thats longer and not as fast...)

Thanks,
  Jason

_______________________________________________

Cocoa-dev mailing list ([email protected])

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 [email protected]

Reply via email to