Reputation:
I'm implementing a singleton class (and lets not get into the discussion if that is wrong or not). I have a method to get the instance of this class, which is lazily initialized:
+ (FFDataManager *)sharedDataManager {
static FFDataManager *dm = nil;
if (!dm) {
dm = [[FFDataManager alloc] init];
}
return dm;
}
Is there anything I should look out for when doing this using static
(inside of the method) as opposed to creating a global variable? Is there anything that can go wrong, all tutorials on the Internet use a global variable.
Upvotes: 2
Views: 123
Reputation: 361
What you create is a static local variable. Static local variables retain their value through successive method invocations. They can only be accessed from within the method which they are defined in. When apps start static local variables are set to 0 once.
So what you do in my opinion is with every call of sharedDataManager
you declare a new static local variable and set it to nil
. I don't think that's necessary or even good. And also every time if (!dm)
checks dm
it is nil
because you set dm to nil the line before.
I'd go with the static global approach.
Edit: Have a look at http://www.johnwordsworth.com/2010/04/iphone-code-snippet-the-singleton-pattern/
Upvotes: -1
Reputation: 53000
To answer the original question (others have address the best way to do initialization):
Is there anything I should look out for when doing this using static (inside of the method) as opposed to creating a global variable?
No.
The difference is over visibility and not lifetime.
static
is visible throughout the whole application. From anywhere else it can be referenced by naming it in an extern
statement.static
is visible just in the containing compilation unit (which is typically a single file, but #import
/#include
can change that).static
is a global which is only visible within that function/method.If you're using a global in just one function what you've done is good - it limits the visibility to just where it is needed while keeping execution-lifetime. Any initializer is run once, just as for file-level globals.
Upvotes: 1
Reputation: 12081
My preferred singleton implementation looks like:
+ (MyClass *) sharedInstance {
static dispatch_once_t predicate = 0;
__strong static MyClass *shared = nil;
dispatch_once(&predicate, ^{
shared = [[self alloc] init];
});
return shared;
}
Using dispatch_once
makes sure this is also thread safe. Your code would allocate twice when accessed by multiple threads at the same time.
Upvotes: 6