views:

762

answers:

3

If I have a class that has a sharedInstance of itself (singleton pattern) or a shared instance of another class, how do I make sure that shared instance is released properly when my program exits? Better yet, can you point me to some documentation about this?

sample class (with all other methods removed for clarity):

@interface Foo : NSObject {
}
+ (Foo*)sharedInstance;

@end

the .m file:

static Foo* SharedInstance;

@implementation Foo

+ (Foo*)sharedInstance
{
    if (!SharedInstance)
        SharedInstance = [[Foo alloc] init]; // possible memory leak?

    return SharedInstance;
}
@end

In the above code, when can I release SharedInstance?

+5  A: 

Unless there are resources beyond the shared instance that need to be released (e.g. files, notifications at cleanup etc.), you can just let the memory for sharedInstance be cleaned up at application exit. Even files and network sockets etc. will be cleaned up by the OS at application exit, so you could get away not cleaning up those as well.

If you do have clean-up actions that need to be taken before application exit, you'll have to add a cleanup or somesuch method to your shared instance and a static method to release the shared instance.

Barry Wark
+3  A: 

Usually there is no need to clean up anything on exit as Barry pointed out, but what you can do is setting an NSApplication delegate that implements

- (void)applicationWillTerminate:(NSNotification *)aNotification

This method is then called right before your application is going to quit. In this method you can call some static method of your shared instance classes to clean up the internally cached shared instance.

However, something like a memory leak beyond application quit doesn't exist. If your application terminates, all memory it ever owned is given back to the system no matter how it was allocated. If that was not the case and your application was going to crash, the memory it used before the crash would be ultimately lost to the system and that is not acceptable. On a multi-tasking OS, an application that crashes must not have any negative effects on the rest of the system!

Mecki
I wouldn't worry about it for singletons, but keep in mind it's still a good practice to release objects even if it's not necessary. It keeps things sane if you ever refactor that code so that memory management does become an issue.
Marc Charbonneau
Yes, but you'd still not release a singleton ref inside the class. What you do is to get a ref to the singleton and treat it as if it was no singleton (e.g. retaining it and later on releasing it), however the ref count never reaches zero, thus the singleton won't go away, not even after release.
Mecki
A: 

It is better to do it like this

  • (Foo*)sharedInstance { if (!SharedInstance) SharedInstance = [[[Foo alloc] init] autorelease];

    return SharedInstance; } @end

Class B which uses the shared instance can retain and release it.

mjs