Re: Singleton instances and multithreading
Re: Singleton instances and multithreading
- Subject: Re: Singleton instances and multithreading
- From: Gareth White <email@hidden>
- Date: Thu, 12 Jul 2001 19:37:37 +0800
At 1:38 AM -0400 12/7/2001, Rob Rix wrote:
>
So, just to be sure that I'm doing the correct thing, here's my singleton
>
method:
>
>
+ sharedScanner
>
{
>
static CBGFileSystemScanner *sharedScanner = nil;
>
NSRecursiveLock *theLock = [[NSRecursiveLock alloc] init];
>
>
[theLock lock];
>
>
if (!sharedScanner)
>
sharedScanner = [[self alloc] init];
>
>
[theLock unlock];
>
>
[theLock release];
>
>
return [sharedScanner autorelease];
>
}
>
>
Is that the right thing to do?
No, your lock should be created only once. The best place to do this is in
+initialize (for a class-wide lock) or in -init (for a lock used by an
individual object).
Try something like this:
static NSLock *sSharedScannerLock = nil;
@implementation CBGFileSystemScanner
+ (void)initialize;
{
static BOOL hasBeenInitialized = NO;
[super initialize];
if (hasBeenInitialized)
return;
hasBeenInitialized = YES;
sSharedScannerLock = [[NSLock alloc] init];
}
+ (CBGFileSystemScanner *)sharedScanner
{
static CBGFileSystemScanner *sharedScanner = nil;
[sSharedScannerLock lock];
if (!sharedScanner)
sharedScanner = [[self alloc] init];
[sSharedScannerLock unlock];
return sharedScanner;
}
Note that usually you won't want to call autorelease on the object you
return because generally you'll want a singleton to stay around until your
program ends. (Unlike, for example, a convenience constructor, which
usually *would* return an autoreleased object.)
Hope that helps,
Gareth