Different ways to initialize singletons
Working in C# and Java, I've seen basically 开发者_StackOverflowone way everybody initializes singletons:
static obj _inst = null;
obj getInstance() {
if (_inst == null) {
_inst = new obj();
}
return _inst;
}
Now, when I move to Objective-C for the iPhone, whenever I see code samples, I see basically the same thing:
static obj _inst = nil;
+ (obj *) sharedObj {
if (!_inst) {
_inst = [[obj alloc] init];
}
return _inst;
}
There's a class method +initialize
that's called on every class in the Objective-C runtime before it's used. Is there any reason I couldn't use that to create my singletons?
static obj _inst = nil;
+ (void) initialize {
if (self == [obj class]) {
_inst = [[obj alloc] init];
}
}
+ (obj *) sharedObj {
return _inst;
}
It works just fine when I try it in my code, and it gets rid of checking to see if it exists every time before it's accessed. Is there any reason I shouldn't create singletons this way?
As far as I'm concerned +initialize
is the way to do it. Peter Hosey suggests a couple of other catches (inside -init
and -allocWithZone:
) to make sure you can't instantiate more than one instance of the class, ever. Thus making it a true singleton class and not just a class with a pointer to a particular instance of itself within it.
Initializing the singleton in +initialize will always allocate the instance. If the instance requires significant resources (including initializarion time which will extend the time before your app becomes responsive at statup) and might not be used, lazy initializarion, as in your examples makes sense.
Lazy Initialization all the way!
I prefer this pattern (similar to what you have):
+ (id) sharedInstance {
static MyObject *sMyObject = nil;
if (!sMyObject) {
sMyObject = [[MyObject alloc] init];
}
return sMyObject;
}
- (oneway void) release {
// no-op
}
There is no need to put this in +(void)initialize for a singleton, since it will only get called when you first attempt to use the class.
精彩评论