Implementing a Singleton in Objective-C / iOS

John WordsworthiOS Development53 Comments

There are many pages of discussions around the internet about whether or not you should use global variables in your applications. I’m not going to to into the depths of these discussions, but I have come to live by the following ethos when it comes to using global variables in my application;

Use them sparingly; Having too many global variables floating around makes it very hard to keep track of what’s going on. I never use more than one global object for each logical section of my code – even if that object contains a handful of other objects from that section.

But you do sometimes need them; I once wrote a small game where I decided not to use my own globals at all. Truth be told, I ended up with a bit of a mess – a large number of similar constructors with a numbers of parameters to link my objects together. Sure, the units were technically separate and didn’t rely on each other – but the reality was, that when you get deep enough into your code – some classes are only ever going to be used in this project (view controllers etc).

Use them when it’s applicable; Generally, global variables are applicable in situations when you’ve got an object / class of which you are only ever going to need one of them and they don’t logically sit as a child of one single part of the application. For instance, the ‘application’ object in some languages – where the object represents the running application.

So, Singleton Eh?

The Singleton model is often used to instantiate just one instance of a class which doesn’t allow a second instance of that same class to be loaded anywhere in the application. Some implementations will throw an exception if you try to create a second instance of the class, some will create the singleton for you when you first try to access it, and some will even let you create other instances if you want, but will always manage a ‘single shared instance’ for you. Many of the core Apple classes follow this pattern, such as [UIApplication sharedApplication].

Anyway, Apple do a very good job (naturally) of providing a good example of the Singleton model. The following code is rather similar to the Apple example, but it also includes what you should have in the header file. It is also a stable part of any library of code snippets, so it has to be here really!

SingletonClass.h

#import <Foundation/Foundation.h>

@interface SingletonClass : NSObject {

}

+ (id)sharedInstance;
@end

SingletonClass.m

#import "SingletonClass.h"

@implementation SingletonClass

static SingletonClass *sharedInstance = nil;

// Get the shared instance and create it if necessary.
+ (SingletonClass *)sharedInstance {
    if (sharedInstance == nil) {
        sharedInstance = [[super allocWithZone:NULL] init];
    }

    return sharedInstance;
}

// We can still have a regular init method, that will get called the first time the Singleton is used.
- (id)init
{
    self = [super init];

    if (self) {
        // Work your initialising magic here as you normally would
    }

    return self;
}

// Your dealloc method will never be called, as the singleton survives for the duration of your app.
// However, I like to include it so I know what memory I'm using (and incase, one day, I convert away from Singleton).
-(void)dealloc
{
    // I'm never called!
    [super dealloc];
}

// We don't want to allocate a new instance, so return the current one.
+ (id)allocWithZone:(NSZone*)zone {
    return [[self sharedInstance] retain];
}

// Equally, we don't want to generate multiple copies of the singleton.
- (id)copyWithZone:(NSZone *)zone {
    return self;
}

// Once again - do nothing, as we don't have a retain counter for this object.
- (id)retain {
    return self;
}

// Replace the retain counter so we can never release this object.
- (NSUInteger)retainCount {
    return NSUIntegerMax;
}

// This function is empty, as we don't want to let the user release this object.
- (oneway void)release {

}

//Do nothing, other than return the shared instance - as this is expected from autorelease.
- (id)autorelease {
    return self;
}

@end

There you go – copy and paste this into your new project, rename the interface and implementations and you’re done – a ready to use Singleton in your project.

Making the creation of your singleton thread safe

Jiunn Harr wrote a great blog post on making the creation of your Singleton thread safe. In the above example, it is possible that your Singleton’s init method could be called more than once, if sharedInstance was called for the first and second time concurrently on different threads. In order to by-pass this problem, you can replace the sharedInstance method above with the following;

+ (SingletonClass *)sharedInstance {
    if (nil != sharedInstance) {
        return sharedInstance;
    }

    static dispatch_once_t pred;        // Lock
    dispatch_once(&pred, ^{             // This code is called at most once per app
        singleton = [[SingletonClass alloc] init];
    });

    return singleton;
}

Note. This doesn’t make all calls on your Singleton thread safe – it simply ensures that the creation of your Singleton is thread safe. This code uses Grand Central Dispatch (Cocoa and iOS4+). To read more about how this works, and why you should consider using it – check out Jiunn Haur’s great blog post on the subject.

Using the Singleton Class

The above code creates the framework for a Singleton class. You can almost ignore the majority of the code above and no go about setting up your own variables and methods for use in your singleton class. It’s worth bearing in mind that when you first attempt to you access your Singleton, it will be created for you, and from that point onwards – it will probably reside in memory for the remainder of your application’s lifecycle. Because of this, you might want to be careful about memory usage and ensure that classes inside your singleton element are tidy.

Accessing your Singleton class from your code is then simply a matter of using the +(SingletonClass*)sharedInstance to get a pointer to the one instance of the singleton class that exists in your application. You can do this anywhere in your code and you would do this for the above class by doing something like the following;

SingletonClass* sharedSingleton = [SingletonClass sharedInstance];
[sharedSingleton callAMethod];

Enjoy!

John WordsworthImplementing a Singleton in Objective-C / iOS

53 Comments on “Implementing a Singleton in Objective-C / iOS”

  1. John Wordsworth

    Hi Nick, thanks for the comment. I’ve updated the article with an additional section at the bottom which describes how you would then use this template class in a real application.

    Essentially, once you’ve added all of the Singleton gunf, you can treat this class as any other class in your codebase and add methods and variables to it as required. Then, you can access the singleton from anywhere in your code with a single line of code – this gives you a reference to the static singleton, creating it if it doesn’t already exist.

    Hope this helps.

    1. John Wordsworth

      Hehe, not a problem! Thanks for clarifying though – I just spent 5 minutes looking through the code trying to figure out what was wrong! Best of luck with your project(s).

  2. ZaldzBugz

    Hi Horace Ho, try to change this method below in your .H file

    + (id)sharedInstance; -> CHANGE TO -> +(SingletonClass*)sharedInstance;

    since + (SingletonClass*)sharedInstance is the one used in the implementation.

    -ZaldzBugz

    1. John Wordsworth

      Hi Adrian, glad that this helped. Yeah, it’s quite a jump going from Java to Objective-C – I’ve got a friend making the same transition now, and I can empathise with the learning curve! Thanks for the feedback.

  3. JK Scheinberg

    I’ve been searching around trying to understand singletons and this is by far the clearest explanation out there. Thanks for putting it up.

    1. John Wordsworth

      Thanks for the positive feedback. I keep meaning to put up some other snippets and tutorials, but it’s a struggle to find the time at the moment. Thanks for commenting.

  4. Nick

    Hello,

    I’m sorry for the trouble but I’m a bit confused about the final use lines that you provided:

    [sharedSingleton callAMethod];

    With the “callAMethod” part, do we create a method in the singleton and set the data to it or am I losing something? I’m very new to this so I apologize for not being able to get my point across well. Thanks in advance.

    Nick

    1. Nick

      Hello Again,

      I actually figured things out myself so no need to reply. This is what I ended up doing:

      I added the following under the *.h:

      NSString *general;

      With a method as follows:

      @property (nonatomic, copy) NSString *general;

      I then added the following under the *.m:

      @synthesize general;

      Then I was able to get and set the saved global information by adding the following under the other object:

      // set the value of the global “general” variable I created in the singleton class

      -(IBAction) setValue:(id)sender {
      [[GlobalsObject sharedInstance] setGeneral:@”test”];
      }

      // get the value of the global “general” variable that was set in the “setValue” action

      -(IBAction) setTextValue:(id)sender {
      barcode.text = [[GlobalsObject sharedInstance] general];
      }

      Thank you so much for posting this amazing tutorial. I am a brand new programmer and without this I would have never been able to complete my project. John Wordsworth, you are the man!

      Nick

  5. Pingback: Using Singletons for iPhone iOS 4 Global Variables « Nick Napier

  6. Van Du

    Hi,

    I think this is wrong:

    // Equally, we don’t want to generate multiple copies of the singleton.
    - (id)copyWithZone:(NSZone *)zone {
    return self;
    }

    it should be:

    + (id)copyWithZone:(NSZone *)zone {
    return self;
    };

    However, will return self still works or do we need to call [self sharedInstance]?

    Thanks,

    1. John Wordsworth

      Hi Van Du,

      I could be wrong, but I’m pretty sure that copyWithZone should be an instance method (-) and not static (+). The method would normally be used to return a new instance that is a copy of the object that you call this method on. We simply return ‘self’ from the shared instance (you would call this [[SingletonObject sharedInstance] copyWithZone:zone]) as we don’t allow for more than one instance of the singleton to exist. See the NSCopying protocol for further details.

      Thanks for the comment, I’m still learning a lot of this as I go – so it’s always interesting to talk over certain points.

    1. John Wordsworth

      Hi Scott, the singleton will only be released when the app closes. Otherwise – the Singleton model is designed to kick around for the lifetime of your application. You could, of course, release elements that exist within your Singleton if you want to clear-up some memory and you’re storing large objects in your Singleton object!

  7. Claudio

    Hey John,

    Great stuff… I was wondering where I would initialize other objects within my singleton? Would you do it after the allocation of the shared instance or use “+initialize” ? Not sure what the “best practice” is…

    if (sharedInstance == nil) {
    sharedInstance = [[super allocWithZone:NULL] init];
    /* WOULD I DO IT HERE */
    }

    I’m still a n00bie with Objective C so I apologize if the question is stupid.

    Thanks,
    Claudio

    1. John Wordsworth

      Hi Claudio, no question is stupid when it comes to programming! Some things might be easier to grasp than others, but it’s actually all pretty complicated stuff when you take a step back and consider it.

      With regards to your question, you don’t really need to treat your Singleton any differently to any other object. I’ve updated the example above to include a template ‘init’ method where you might want to include your normal initialisation-type code for this object. The init method will only be called once, and that will be just before the first time you get your hands on the singleton (the first time you call [SingletonClass sharedInstance]).

      The only major caveat, is that you want to err away from init method that take parameters. As you’re not expected to care when / where your Singleton is initialised (it could be called anywhere in your code) it’s best to veer away from having any ‘initWith’ methods. It’s preferable to have a basic init method that sets up any required sub-objects and then you can configure those objects with additional instance methods on the singleton.

      Hope this helps, if you have any further problems, or this isn’t very clear – please don’t hesitate to drop me another message.

  8. Ajaxjava

    Can this [[SingletonClass alloc] init] still be called to create a new object? If yes, how to guarantee there is only one object in the memory?

    1. John Wordsworth

      Hi AjaxJava – thanks for dropping by and posting your comment. I hope my response helps to clear things up.

      As we have overridden allocWithZone: calling [SingletonClass alloc] will in turn call allocWithZone:, which simply returns the one singleton copy of this object (by calling the +sharedInstance method). If the static object does not exist already, then it will be created during the alloc call and a reference to it returned. Either way, you are still providing access to the one and only singleton object that exists in memory. Therefore, calling [[SingletonClass alloc] init] will return the one single copy of this class (creating it if necessary) and then call the init method on that instance. It is the overridden allocWithZone method that ensures that another copy of this object is never created in memory.

      If you are in a situation where you need to have a single copy of this class that is controlled and accessed by using [SingletonClass sharedInstance] but would also like to be able to create other copies of this class for other uses, then you can remove the methods allocWithZone:, copyWithZone, retain, retainCount, release, autorelease from the above code listing (basically, remove all methods except sharedInstance and init). This removes the restraint that only one copy of this class may ever exist, so only the one created by the sharedInstance method will be managed for you – you will have to memory manage all other copies of this class that you make yourself. Personally, i would err away from doing this, as I prefer to think that a class is either a Singleton or not (and not some strange hybrid), but the choice is yours!

  9. Pingback: Implementing a thread-safe Singleton in iOS | ampersand

  10. Dustin Pfannenstiel

    Am I missing something? How are you avoiding recursion hell…

    You call the sharedInstance. If it’s nil allocWithZone. Then in allocWithZone you return the sharedInstance, which requires calling sharedInstance. At this point it should still be nil so call allocWithZone…

    And repeat until insane.

    1. Dustin Pfannenstiel

      Never mind… problem existed between keyboard and chair. Call super’s allocWithZone.

  11. Jared

    Shouldn’t this line:

    static SingletonClass *sharedInstance = nil;

    Go before the @implementation tag? I don’t think you can declare any variables inside it.?

    1. John Wordsworth

      Hi Jared. Thanks for the comment.

      I have always declared my static variables just under the @implementation tag and never run into any problems before. I believe that the only variables you can declare within the @implementation section of a class are static variables (unless you use @implementation{ variables } construct – which is a relatively new feature I think). I’m fairly confident that declaring the static variable before or after the @implementation tag has exactly the same result and is simply down to style choice (I’ve seen both in libraries).

  12. Van Du Tran

    I think in the thread save section ther’es an error:

    01
    02
    03
    04
    05
    06
    07
    08
    09
    10
    11
    12
    + (SingletonClass *)sharedInstance {
    if (nil != sharedInstance) {
    return sharedInstance;
    }

    static dispatch_once_t pred; // Lock
    dispatch_once(&pred, ^{ // This code is called at most once per app
    singleton = [[SingletonClass alloc] init];
    });

    return singleton;
    }

    it should be

    sharedInstance = [[SingletonClass alloc] init];
    and return sharedInstance;

    Also, why is it in this case we do not call the initWithZone() but the regular init()?

    1. Van Du Tran

      Also, why in one case we have “sharedInstance = [[super alloc] initWithZone()] and in the other case we have “sharedInstance = [[SingletonClass alloc] init]

  13. Osni Oliveira

    Hi John,

    Thank you for your post, I found it to be very useful.
    Just a doubt here, your code for the allocWithZone overriding is:

    // We don’t want to allocate a new instance, so return the current one.
    + (id)allocWithZone:(NSZone*)zone {
    return [[self sharedInstance] retain];
    }

    If sharedInstance is a static variable not bout to the class implementation (proof of that is you can declare it inside or outside the @implementation section), why use self? And, most important yet, why call retain on sharedInstance, since you also override the retain method to do nothing and just return self?

  14. Pingback: Alex Westholm» Blog Archive » Reflections on one month of iOS development: Part II

  15. Oliver

    I don’t understand…
    In you rchapter “Making the creation of your singleton thread safe”, if I use the replace code, where is sharedInstance set ? It’s never initialised nor filled…

  16. Mike

    I’ve long been looking to store globals.
    I did LabView programming for 2 years, so the structure of programming isn’t new in itself, but still, this is a whole new world.

    I played around with the singleton and I think for what I want to do, it’s perfect. But I have a problem when using storyboard.
    I have a segue that switches from my 1st to my 2nd viewcontroller. If I put a button on the 2nd view and implement to update a label on the view with my string from the singleton, the label gets updated.
    If I put the assignment of my singleton string to the label under viewdidload, I always get null.

    What can I do here to solve this issue?

    Thanks.

    BTW, great post.

  17. Lee McLaughlin

    Hi,

    Thanks, very good tutorial.

    I think there is a slight typo/cop-over mistake here:

    + (SingletonClass *)sharedInstance {
    if (nil != sharedInstance) {
    return sharedInstance;
    }

    static dispatch_once_t pred; // Lock
    dispatch_once(&pred, ^{ // This code is called at most once per app
    sharedInstance = [[SingletonClass alloc] init];
    });

    return sharedInstance;
    }

    ^ have switched the ‘singleton’ variable to sharedInstance

    Thanks Again,

    Lee

  18. mrEmpty

    This code gives me a ton of errors, forbidden use of ‘super’ and ‘retain’ by ARC. Same with retain count etc. Everything from -(void)dealloc down throws errors. No idea why.

    1. Travis Beck

      If you’re using ARC you can just remove the following:

      // Your dealloc method will never be called, as the singleton survives for the duration of your app.
      // However, I like to include it so I know what memory I’m using (and incase, one day, I convert away from Singleton).
      -(void)dealloc
      {
      // I’m never called!
      [super dealloc];
      }

      // Once again – do nothing, as we don’t have a retain counter for this object.
      - (id)retain {
      return self;
      }

      // Replace the retain counter so we can never release this object.
      - (NSUInteger)retainCount {
      return NSUIntegerMax;
      }

      // This function is empty, as we don’t want to let the user release this object.
      - (oneway void)release {

      }

      //Do nothing, other than return the shared instance – as this is expected from autorelease.
      - (id)autorelease {
      return self;
      }

      AND CHANGE allocWithZone: to:

      // We don’t want to allocate a new instance, so return the current one.
      + (id)allocWithZone:(NSZone*)zone {
      return [self sharedInstance];
      }

  19. Chet

    The thread safe +sharedInstance method is wrong — you changed up the variable name.

    It should be:

    + (CurrentUser *)sharedInstance {
    if (nil != sharedInstance) {
    return sharedInstance;
    }

    static dispatch_once_t pred; // Lock
    dispatch_once(&pred, ^{ // This code is called at most once per app
    sharedInstance = [[CurrentUser alloc] init];
    });

    return sharedInstance;
    }

  20. Vincent Tanakas

    Hi, thanks for the article, but it seems that the code as posted results in a recursive deadlock. The sharedInstance method invokes the allocWithZone method which in turn invokes the sharedInstance method, before the sharedInstance pointer is assigned.

    When I run the code as listed (with the correction of renaming ‘singleton’ to ‘sharedInstance’, I deadlock.

    Commenting out the updated allocWithZone method will resolve this, but then it’s possible to bypass the lock if the user directly allocates a singleton using the alloc/init mechanism.

    1. Vincent Tanakas

      Looks like Dustin’s earlier post resolves this issue:
      + (SingletonClass *)sharedInstance {
      if (nil != sharedInstance) {
      return sharedInstance;
      }

      static dispatch_once_t pred; // Lock
      dispatch_once(&pred, ^{ // This code is called at most once per app
      singleton = [[super allocWithZone:NULL] init]; // Just calling [super alloc] would result in [self allocWithZone:NULL] getting called which would lead to a recursive block.
      });

      return singleton;
      }

  21. Pingback: Singleton Design Pattern « jamesdevnote

  22. Pingback: iOS4 – Static Classes | Russell Broadbent

  23. Ron L

    It is clear that we are eliminating multiple attempts to alloc the singleton. However, multiple calls to init seem possible and probable. After the singleton is allocated and initialized, does NSObject simply ignore future init calls?

    Example:

    SingletonClass *myObject=[[SingletonClass alloc]init];
    SingletonClass *moOtherAttempt=[[SingleClass alloc]init];

    the alloc call returns the sharedInstance. We then call init on the sharedInstance. Is this a problem?

    Thanks

  24. viktorvogh

    Thanks buddy. Worked like a charm.

    Had to disable Auto Reference Counting (ARC) in the project properties to make some methods legal. (iOS 6 SDK, Xcode 4.5.2)

    The other option is enabling ARC and removing the dealloc, retain, retainCount, release and autorelease methods.

  25. Thomas LEDUC

    Hello,

    Thanks a lot for this great example, but I have a little problem in thread safe singleton :
    static dispatch_once_t pred; // Lock
    dispatch_once(&pred, ^{ // This code is called at most once per app
    singleton = [[SingletonClass alloc] init];
    });

    return singleton;

    the var “singleton” is a mistake ? We must use “sharedInstance” isn’t it ?

  26. Pingback: iOS设计模式(02):单例模式 | 破船之家

  27. Jay Long

    Finally ! The whole package! Thanks for this!

    I know its using globals, but sometimes living in sin makes sense !

  28. Pingback: objc short call for singletonCopyQuery CopyQuery | Question & Answer Tool for your Technical Queries,CopyQuery, ejjuit, query, copyquery, copyquery.com, android doubt, ios question, sql query, sqlite query, nodejsquery, dns query, update query, insert

  29. Johnc381

    hi!,I really like your writing so so much! proportion we communicate more about your post on AOL? I need a specialist on this space to unravel my problem. Maybe that’s you! Looking ahead to see you. dcdbdedbddfd

  30. Pingback: Singleton Design Pattern In Objective C

Leave a Reply

Your email address will not be published. Required fields are marked *