views:

135

answers:

6

Does anyone have any preferences or comments about using either ...

static id sharedReactor = nil;

+(id)sharedInstance {
if(sharedReactor == nil) sharedReactor = [[super allocWithZone:NULL] init];
return sharedReactor;
}

OR:

static id sharedReactor = nil;

+(void)initialize {
if(sharedRandomReactor == nil) {
sharedRandomReactor = [[super allocWithZone:NULL] init];
}

+(id) sharedInstance {
    return sharedReactor;
}

To my mind using +(void)initialize seems a lot more elegant, I am just curious what people with more experience than myself think of both approaches?

gary

A: 

I prefer +(id)instance and a local static within the method itself. (more like the first example)

Pestilence
A: 

The problem with the first option is that you now have one more responsibility which is calling the "Initialize" => more possible bugs.

However, the advantage of the second is that after you initialized the instance one, the code no longer checks if it's nil, so it's saves you few CPU cycles.

Even though, I'd go with the first one..

The +initialize method is called by the runtime system immediately after it first loads the class into memory. Your code should never call this method directly.
jlehr
+2  A: 

From Mike Ash's site here is another way using Grand Central Dispatch:

+ (id)sharedWhatever
{
    static dispatch_once_t pred;
    static Whatever *whatever = nil;
    dispatch_once(&pred, ^{
        whatever = [[Whatever alloc] init];
    });
    return whatever;
}
Abizern
But does libdispatch exist on iPhone OS? (See tags)
Sixten Otto
A: 

This is the way to go...

static id sharedReactor = nil;

+(id)sharedInstance {
if(sharedReactor == nil) sharedReactor = [[super allocWithZone:NULL] init];
return sharedReactor;
}

Much clearer from both methods.

Jordan
Why not just [[self alloc] init] rather than [[super allocWithZone:nil] init]?
jlehr
Also, why expose the static variable outside the scope of the +sharedInstance method?
jlehr
The static variable needs to be only allocated once.
Jordan
Static variables are allocated at compile time, so they can only be allocated once no matter where they appear in your code. The only difference in this case is the scope of the variable, i.e. where it's visible. The extent is always infinite.
jlehr
@jlehr, thank you for your comments, [super allocWithZone:NULL] was originally from the Apple example. I am now looking at changing that as I want to move away from enforcing singularity and more towards a singleton that would allow multiple instances if needed. With regards to the static variable, yes that will be going inside the +sharedInstance method. Initially I was using it in multiple methods, but now I am not so its safe to put it back.
fuzzygoat
A: 

I've always followed the suggestions in the Cocoa Fundamentals guide from Apple - http://bit.ly/Cvfd8. This way it doesn't matter if the class is instantiated multiple times, or accessed through a sharedInstance class method the object returned is always the same.

The guide also highlights the redefining the retain/release to prevent its resources from ever being reclaimed. Just FYI.

pryomoax
A: 

I just spotted a blog entry from bbum regrading the possibility that +initialize can be executed more than once if a subClass does not implement it but the superClass does. As long as you keep this foible in mind +(void)initialize might well be the best option, particularity where you need thread safety and you don't want to take the hit of using @synchronized. After saying that if you just looking for simple singleton to use as a shared data model and are not to worried about thread safety then go with the first one.

fuzzygoat