0

I often see singleton classes designed similar to the following:

@implementation SomeImplementation

static SomeClass *sharedSomeObject = nil;

+ (void) someClassMethod {
   sharedSomeObject = [[SomeImplementation alloc] init];
   // do something
}

@end

someClassMethod can be called at any time -- should it be checking for nil first before allocating a new instance of sharedSomeObject? Or, since sharedSomeObject is static, is the check unnecessary? Seeing code like this I always want to put an if (!sharedSomeObject) around the allocation.

memmons
  • 40,222
  • 21
  • 149
  • 183

2 Answers2

3

Yes, absolutely! Otherwise you're creating more than one object every time your method is called. This is how we do things:

+ (SomeClass *) shared {
    static SomeClass    *sSingleton;

    if ( ! sSingleton ) sSingleton = [SomeClass new];

    return sSingleton;
}

EDIT

This answer is very old, not thread-safe, and no longer an appropriate singleton initialization method. See this Stackoverflow answer for the correct way of doing things nowadays with GCD.

Community
  • 1
  • 1
par
  • 17,361
  • 4
  • 65
  • 80
  • Note that the function-static declaration is intentional. It helps keep the code clean and reduces visibility only to the + shared method. By doing it this way you can also reuse the name "sSingleton" wherever you like. No namespace pollution. – par Jan 13 '11 at 04:17
  • I'll also point out that your code above if implemented as-is leaks the previous instance of sharedSomeObject every time you call someClassMethod. Ack! – par Jan 13 '11 at 04:20
  • Thanks for that. Glad I wasn't going crazy. So, if implementing sSingleton that way, how do you release it? I'm thinking there are probably cases where I'd want to release it to save memory and recreate it at need. – memmons Jan 13 '11 at 04:45
  • you wouldn't in this case. many NSObject subclass singletons also override `retainCount`. the allocation is just returned after the process has exited (assuming of course the method was executed). you'll need a more robust approach if you want to destroy it. – justin Jan 13 '11 at 05:42
  • The reason you create a singleton is because you need an object with a persistent state even though access is arbitrary. The expectation then is that once you call +shared the object persists for the lifetime of the application. It's an intentional leak. As a result you need to design carefully to ensure a singleton is really necessary. If you need to reclaim the memory you should use the traditional retain/release model, the implication being that a release means you don't care to maintain persistent state (or you've got some save/restore mechanism if you do). – par Jan 13 '11 at 19:41
  • This code is not thread safe. You should use GCD. Just Google GCD singleton. – Maciej Swic Jul 01 '14 at 08:00
2

When it comes to the using the Singleton design pattern with Objective-C, I can highly recommend using Matt Galagher's "SynthesizeSingleton.h" macro. It deals with all the singelton-related topics like freeing (is that a proper word?) memory if the singleton will be no longer needed.

Here's the link to the "Cocoa with Love" website which contains an article on this topic as well as a link for the download of the "SynthesizeSingleton.h" header file:

http://cocoawithlove.com/2008/11/singletons-appdelegates-and-top-level.html

You will also find a discussion on using global variables vs. using the Singleton design pattern as well as some considerations on different approaches towards using Singletons there.

MatthiasC
  • 344
  • 1
  • 3
  • 15
  • 1
    Great post. We'll start using this, I like the fact that Matt's code is thread safe and it goes to some trouble to avoid releasing the singleton. The only thing I'd change is the concatenation of the class name (too much typing). + (SomeClass *) shared; seems cleaner. – par Jan 15 '11 at 00:21