Re: Maintaining *one* singleton over >1 thread
Re: Maintaining *one* singleton over >1 thread
- Subject: Re: Maintaining *one* singleton over >1 thread
- From: Brant Vasilieff <email@hidden>
- Date: Tue, 18 Mar 2003 11:50:07 -0800
I wouldn't set them to nil in the initialize, but rather when they are
defined. So at the top of the file would be:
static InstanceClass* MyClass_sharedInstance = nil;
Then in your +(void)initialize method test for nil before creating the
sharedInstance. It's necessary to test for nil, because +initialize
can get called more than once.
+(void)initialize
{
if (MyClass_sharedInstance == nil) // Line A
MyClass_sharedInstance = [[MyClass alloc] init]; // Line B
}
Now your +sharedInstance can be as simple as:
+ (MyClass*)sharedInstance
{
return MyClass_sharedInstance;
}
The instance itself should probably store it's own lock to protect it's
contents. Jeff's tips for delaying the introduction of the lock until
you become multithreaded is a good one, however, it's not entirely cost
free as it still must perform a runtime check for != nil.
If the shared instance can be replaced during the execution of the
application then you may want to introduce locks within
+sharedInstance. The potential weakness of the above sample, is that
it may be possible for the first thread to be interrupted between lines
A & B. In that case you may end up with a leaked redundant
sharedInstance. Two ways around this. One is to call [MyClass
initialize] before creating any threads. The other is to use a
sharedLock, that exists prior to your +initialize method getting
called, to protect the initialization.
Also NSWillBecomeMultiThreadedNotification is only sent once, when the
first thread is detached. So you can't rely on
NSWillBecomeMultiThreadedNotification to create your lock.
In your sharedInstance, if you want to protect it's contents with a
lock, then in the init method you should test to see if you are
currently multithreaded using [NSThread isMultiThreaded].
- (id)init
{
if (self = [super init])
{
lock = [NSThread isMultiThreaded] ? [[NSLock alloc] init] : nil;
// Register for NSWillBecomeMultiThreadedNotification.
// The rest of your init.
}
return self;
}
Cheers,
Brant
On Tuesday, March 18, 2003, at 01:58 AM,
email@hidden wrote:
>
Then, in the + (void)initialize method of the class, set
>
them to nil and register the class as the receiver of the
>
NSWillBecomeMultiThreadedNotification notification.
>
>
On Monday, March 17, 2003, at 08:34 PM, sinclair44 wrote:
>
> Hello-
>
>
>
> I'm writing a multithreaded app with a singleton that must be
>
> allocated
>
> *exactly once*. I was doing it (when single-threaded) with
>
> +sharedInstance
>
> and a static variable. However, when the second thread calls
>
> +sharedInstance, a new instance is allocated (which didn't happen
>
> before)!
>
>
>
> Is there an easy way to get a single instance of this singleton over
>
> the
>
> entire app?
_______________________________________________
cocoa-dev mailing list | email@hidden
Help/Unsubscribe/Archives:
http://www.lists.apple.com/mailman/listinfo/cocoa-dev
Do not post admin requests to the list. They will be ignored.