views:

84

answers:

3

Can anyone tell me what the scope of the static variable in the class below is?

@implementation SharedManager

static id myInstance = nil;

+(id)sharedInstance {
    if(myInstance == nil) {
        myInstance = [[self alloc] init];
    }
    return myInstance;
}

In a test I created an instance from the class and then released it, but noticed that on creating a second instance that the static was not nil (i.e. pointing to the previously released object) For the test I fixed this by overriding -(void)dealloc for the class.

-(void)dealloc {
    NSLog(@”_deal: %@”, [self class]);
    [super release]
    myInstance = nil
}

gary

A: 

As far as I understand, the visibility scope of that variable is below its declaration within the current source file, and the lifetime is global. As if it's a C static variable.

In other news, you can write C functions within the @implementation block - they'll work like regular C functions.

There's no notion of "class static" variables in ObjC, AFAIK. This is not C++.

Seva Alekseyev
Thank you, not sure about the "C Function" bit, the code shows "Objective-C Class Methods" ... but I could always be missing your point.
fuzzygoat
Because Objective-C is C with O-O extensions, you can always do plain old C stuff, plus you can mix and match. What Seva is talking about is writing plain old C functions that contain Objective-C code. (Take a look at Apple's Foundation Functions reference for some examples.) As Seva points out, those can be placed anywhere in a .m file.
jlehr
Ah I see, thanks for the clarification.
fuzzygoat
+1  A: 

The scope of the variable is limited to the "SharedManager" class itself (since it's declared in the @implementation section, it will not be visible to subclasses).

The duration of the variable is "static" meaning that there's one copy of the variable associated with the class itself; it does not get created/destroyed when you alloc/dealloc instances of the class.

Also; if your class is intended to be thread-safe, you should do

@synchronized(self) {
if (myInstance == nil) {
    myInstance = [[self alloc] init];
}

to your sharedInstance method, to handle the case of two threads simultaneously calling sharedInstance.

David Gelhar
Thank you David, yes I appreciate that, but in this case the singleton is simply for the model data, its a simple MVC iPhone application and I don't foresee and threading happening. I just wanted to make sure how it was working, hence the unneeded dealloc as I don't see it being released either
fuzzygoat
Just a quick note from my singleton travels, @synchronized([SharedManager class]) { might work better, or so I have been led to believe.
fuzzygoat
A: 

Singletons aren't ordinarily released, since there's only one instance for your whole app. Creating a second instance of a singleton seems to me to be violating the intent of the pattern; not sure why you'd want to do that.

While it's great to understand the ramifications of all the corner cases, most apps don't need really fancy, threadsafe, etc. singleton implementations. So unless you're writing a framework, or are working on a fairly complex Cocoa app, you probably won't need a bullet-proof mechanism.

jlehr