The Objective-C Singleton

Aug 30, 2009   //   by Derek van Vliet   //   Development  //  33 Comments

One of the most useful patterns that we have employed in our iPhone game is the singleton. For those who don’t know, singletons are a class that only gets instantiated once in your application’s run-time. They often take the form of manager or factory classes. A good example of a singleton is the web-based resource manager class that we posted about recently.

We have been using singletons for a variety of things in our cocos2d-based game. Including:

  • Resource management
  • Atlas sprite managers
  • User settings management
  • Score management

Below is a template for the singletons that we use in objective-c.

MySingleton.h:

#import <Foundation/Foundation.h>
 
@interface MySingleton : NSObject {
 
}
+(MySingleton*)sharedMySingleton;
-(void)sayHello;
@end

MySingleton.m:

@implementation MySingleton
static MySingleton* _sharedMySingleton = nil;
 
+(MySingleton*)sharedMySingleton
{
	@synchronized([MySingleton class])
	{
		if (!_sharedMySingleton)
			[[self alloc] init];
 
		return _sharedMySingleton;
	}
 
	return nil;
}
 
+(id)alloc
{
	@synchronized([MySingleton class])
	{
		NSAssert(_sharedMySingleton == nil, @"Attempted to allocate a second instance of a singleton.");
		_sharedMySingleton = [super alloc];
		return _sharedMySingleton;
	}
 
	return nil;
}
 
-(id)init {
	self = [super init];
	if (self != nil) {
		// initialize stuff here
	}
 
	return self;
}
 
-(void)sayHello {
	NSLog(@"Hello World!");
}
@end

Example Usage

Using the methods of the singleton is then as easy as this:

[[MySingleton sharedMySingleton] sayHello];

33 Comments

  • Dear,

    Thanks for the tutorial, I think I got it working however, the singleton itself works ok I think but now i want to share a simple NSString in it. I want to be able to set it and get it.

    header file:
    Code:

    #import <Foundation/Foundation.h>
    @interface Global : NSObject {
    NSString *test;
    }

    @property (nonatomic, retain) NSString* test;

    +(Global*)sharedMySingleton;
    -(void)sayHello;
    @end

    implementation:
    Code:

    #import “Global.h”

    @implementation Global

    @synthesize test;

    static Global* _sharedMySingleton = nil;

    +(Global*)sharedMySingleton
    {
    @synchronized([Global class])
    {
    if (!_sharedMySingleton) {
    [[self alloc] init];
    }

    return _sharedMySingleton;
    }

    return nil;
    }

    +(id)alloc
    {
    @synchronized([Global class])
    {
    NSAssert(_sharedMySingleton == nil, @”Attempted to allocate a second instance of a singleton.”);
    _sharedMySingleton = [super alloc];
    return _sharedMySingleton;
    }

    return nil;
    }

    -(id)init {
    self = [super init];
    if (self != nil) {
    // initialize stuff here
    }
    return self;
    }

    -(void)sayHello {
    NSLog(@”test has value: %@”,self.test);
    }

    @end

    This works from an other class where I try to access the singleton:
    Code:

    [Global sharedMySingleton].test = @”first assignment”;
    [[Global sharedMySingleton] sayHello];

    But when I try the next thing then my application terminates:
    Code:

    NSLog(“singleton: %@”,[Global sharedMySingleton].test);

    I also get the warning: warning: passing argument 1 of 'NSLog' from incompatible pointer type

    Any help is highly appriciated, I think i'm missing something coceptually.

  • duponol, when I copied your code into xcode it worked as expected. I see the following output in the console:

    test has value: first assignment

    Are you writing an iPhone app or another type of mac app?

  • Hey Derek,

    I'm embaressed to say it but I found my error, it was the second piece of code that diden't work:

    NSLog(“singleton: %@”,[Global sharedMySingleton].test);

    There is no @ in front of the “singleton: %@”, I was so hang up in the singleton that I wasn't seeing clear. Sorry for your trouble and thanks for the reply and the tutorial.

    Kind regards,
    Olivier

  • duponol, when I copied your code into xcode it worked as expected. I see the following output in the console:

    test has value: first assignment

    Are you writing an iPhone app or another type of mac app?

  • Hey Derek,

    I'm embaressed to say it but I found my error, it was the second piece of code that diden't work:

    NSLog(“singleton: %@”,[Global sharedMySingleton].test);

    There is no @ in front of the “singleton: %@”, I was so hang up in the singleton that I wasn't seeing clear. Sorry for your trouble and thanks for the reply and the tutorial.

    Kind regards,
    Olivier

  • Thanks for the tutorial. Works perfectly. I'm new to ObjC programming for iphone.

    i tried to have a NSArray instead of NSString except i dont know the syntax for accessing it.

    [[MySingleton sharedMySingleton] [myArray arrayWithObjects: @"test", nil]];

    How do i achieve this?

  • [MySingleton sharedMySingleton].QQQ = [NSArray arrayWithObjects: @"test", nil];
    I think this is the correct syntax.

    How do I do something like [MySingleton sharedMySingleton] [QQQ objectAtIndex:0]; ?

    thanks in advance

  • Where do you instantiate this from? I tried from inside viewDidLoad on a UIView, and was told in an IBAction method further up that the instance was undeclared…

    Where do you instantiate to ensure all methods can access it?

  • Hi, I've tried this code. But I got “error: 'VariableStore' undeclared (first use in this function)” message when trying to use it. Anything wrong? Plz help.

    I rename MySingleton to VariableStore. Thanks.

  • Hi, I've tried this code. But I got “error: 'VariableStore' undeclared (first use in this function)” message when trying to use it. Anything wrong? Plz help.

    I rename MySingleton to VariableStore. Thanks.

  • Nice article !
    For people who are interested I made a reusable singleton class on this blog:
    http://www.devbypractice.com/reusable-singleton…

  • very thanks man.

    it works fine for me………….

    Thanks a lot

  • Great Thanks…It’s the best tutorial.

  • Great Thanks…It’s the best tutorial.

  • Great Thanks…It’s the best tutorial.

  • Great Thanks…It’s the best tutorial.

  • hello,
    i think there is some missing

    + (id)allocWithZone:(NSZone *)zone {
    @synchronized([MySingleton class]) {
    NSAssert(_sharedMySingleton == nil, @”Attempted to allocate a second instance of a singleton.”);
    _sharedMySingleton= [super allocWithZone:zone];
    return _sharedMySingleton; // assignment and return on first allocation
    }
    return nil; //on subsequent allocation attempts return nil
    }

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

    - (id)retain {
    return self;
    }

    - (unsigned)retainCount {
    return UINT_MAX; //denotes an object that cannot be released
    }

    - (void)release {
    //do nothing
    }

    - (id)autorelease {
    return self;
    }

  • [...] Source : getsetgames This entry was posted in Uncategorized by Guerrix. Bookmark the [...]

  • [...] del Post : getsetgames This entry was posted in Apple, iPad, iPhone, Mac, Objective-C by Guerrix. Bookmark the [...]

  • fine thanks

  • Should be like this:[[MySingleton sharedMySingleton].QQQ objectAtIndex:0];”[MySingleton sharedMySingleton].QQQ” evaluates to a pointer to QQQ so it’s the same as:NSArray *QQQ = [MySingleton sharedMySingleton].QQQ;id *whatever = [QQQ objectAtIndex:0];

  • sorry that formatting came out pretty badly. I’ll try again:

    Should be like this:[[MySingleton sharedMySingleton].QQQ objectAtIndex:0];

    “[MySingleton sharedMySingleton].QQQ” evaluates to a pointer to QQQ so it’s the same as:

    NSArray *QQQ = [MySingleton sharedMySingleton].QQQ;

    id *whatever = [QQQ objectAtIndex:0];

  • I was wondering how to do this, thank you!

  • [...] class.  What is a singleton class you might be asking?  A good quick tutorial can be found here.  Basically it is a class that only gets instantiated once in an application.  They are very [...]

  • Excellent concise tutorial, thanks!

  • [...] = "#000000"; ch_color_bg = "#FFFFFF"; I set up a singleton following the instructions at this tutorial, but when I analyze it I see the following memory [...]

  • Nice Tutorial 

  • Thanks!

  • [...] common way to share data across classes in iOS apps is by following the singleton [...]

  • I am beginner in IOS . What all things i need to do access the method ” say hello ” from my other class.

  • Thanks, really gud tutorial

  • Thanks! This helped a lot!

  • What is @synchronized?

Leave a comment

Our Games

Latest Tweets