On 12 Nov 2012, at 12:56, "Gerriet M. Denkmann" <[email protected]> wrote:
> I have a property:
>
> @property (readonly) NSDictionary *someDictionary;
>
> This property should be computed on demand, and should be accessible by
> several threads.
>
> My current implementation is:
>
> - (NSDictionary *)someDictionary;
> {
> static NSDictionary *someDictionary;
> static dispatch_once_t justOnce;
> dispatch_once( &justOnce, ^
> {
> // create a temp dictionary (might take some time)
> someDictionary = temp;
> }
> );
>
> return someDictionary;
> }
>
> The first thread which needs someDictionary will trigger its creation. Ok.
>
> But what happens when another thread wants to access someDictionary while it
> is still being created? I guess it will receive just nil.
> This would be not correct; it really should wait until the dictionary is
> ready.
>
> How to achieve this? Use a lock? Use @synchronize?
This is completely the wrong way to implement a property. The static variable
will be shared between all instances. Here's how you should be doing a lazy
loaded var:
@implementation MyClass
{
NSDictionary *_someDictionary
}
- (NSDictionary *)someDictionary
{
static dispatch_once_t justOnce;
dispatch_once(&justOnce, ^
{
someDictionary = [[NSDictionary alloc] initWithObjectsAndKeys: ……
nil];
});
return someDictionary;
}
In answer to your threading question. If multiple threads ask for the
dictionary at once, the second one to hit the dispatch_once will block until
the first one has finished the dispatch_once block, and then continue to
execute (without touching the contents). Thus, both threads will receive the
same dictionary (assuming it's the same instance it's called on), and it will
be allocated only once.
Tom Davie
_______________________________________________
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:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com
This email sent to [email protected]