One of my most used design patterns when developing for iOS is the singleton pattern. It’s an extremely powerful way to share data between different parts of code without having to pass the data around manually. More about the singleton pattern and other patterns can be found in this excellent book:
Singleton classes are an important concept to understand because they exhibit an extremely useful design pattern. This idea is used throughout the iPhone SDK, for example, UIApplication has a method called sharedApplication which when called from anywhere will return the UIApplication instance which relates to the currently running application.
You can implement a singleton class in Objective-C using the following code:
MyManager.h
#import <foundation/Foundation.h>
@interface MyManager : NSObject {
NSString *someProperty;
}
@property (nonatomic, retain) NSString *someProperty;
+ (id)sharedManager;
@end
MyManager.m
#import "MyManager.h"
static MyManager *sharedMyManager = nil;
@implementation MyManager
@synthesize someProperty;
#pragma mark Singleton Methods
+ (id)sharedManager {
@synchronized(self) {
if (sharedMyManager == nil)
sharedMyManager = [[self alloc] init];
}
return sharedMyManager;
}
- (id)init {
if (self = [super init]) {
someProperty = [[NSString alloc] initWithString:@"Default Property Value"];
}
return self;
}
- (void)dealloc {
// Should never be called, but just here for clarity really.
}
@end
If you are not using Automatic Reference Counting (ARC), then you should use the following code:
MyManager.m
#import "MyManager.h"
static MyManager *sharedMyManager = nil;
@implementation MyManager
@synthesize someProperty;
#pragma mark Singleton Methods
+ (id)sharedManager {
@synchronized(self) {
if(sharedMyManager == nil)
sharedMyManager = [[super allocWithZone:NULL] init];
}
return sharedMyManager;
}
+ (id)allocWithZone:(NSZone *)zone {
return [[self sharedManager] retain];
}
- (id)copyWithZone:(NSZone *)zone {
return self;
}
- (id)retain {
return self;
}
- (unsigned)retainCount {
return UINT_MAX; //denotes an object that cannot be released
}
- (void)release {
// never release
}
- (id)autorelease {
return self;
}
- (id)init {
if (self = [super init]) {
someProperty = [[NSString alloc] initWithString:@"Default Property Value"];
}
return self;
}
- (void)dealloc {
// Should never be called, but just here for clarity really.
[someProperty release];
[super dealloc];
}
@end
Then you can reference the singleton from anywhere by calling the following function:
MyManager *sharedManager = [MyManager sharedManager];
I’ve used this extensively throughout my code for things such as creating a singleton to handle CoreLocation or CoreData functions.
EDIT: Added property to MyManager.
EDIT: Updated as per Apple’s guidelines to pass static analysis.
EDIT: Updated to support ARC.


thank for nice code.
Thank you!
Hi
I m newbie in iphone . My problem is pass one view controller variable to the thirdview controller in the url string.
MyManager *sharedManager = [MyManager sharedManager];
where i write these code in application?
thanx.
First let me clarify that in my comment I mean no disrespect, I am just, respectfully, in disagreement with your solution.
I do not really fully understand why you are overwriting NSObejct’s reference counting and memory management functions (which is, IMHO, bad practice) these methods. Since the singleton variable holds ownership of the object, you are pretty much protecting yourself simply from someone calling “release” one too many times – but in this case the solution is KNOWING you are doing this and not sweeping the problem underneath a rug (for example NSLog’ing the functions and still calling the parent). Probably, if someone releases the singleton, the problem is really something bigger.
@Yoav – I think you are missing the point of the singleton pattern slightly. The way I have shown to implement it is the same way Apple show to implement it and they use it all over their code.
A singleton, by definition of the pattern, has a life cycle the same as the process.
[...] http://iphone.galloway.me.uk/iphone-sdktutorials/singleton-classes/ [...]
On line 36, you have a single ‘=’ in your if statement, was it intentional?
After reading the other comment about it and your reply, I understand.
@Nacereddine – Yes, it means “set self to the return of [super init] then check if that is non-nil”.
The code above looks great, but then how do you share var to the other modules?
@Mark – How do you mean? You access the ivars of your singleton just using the synthesised setters/getters or custom setters/getters that you define.
Matt thanks for the response. I am new to iPhone and ObjC so still trying to understand what is needed. Where can I read something that would explain the setter and getter? I assume that is similar like in Java? Is there no way to access the vars without the settter/getter? thanks for the tutorial!!
@Mark – I suggest reading some of the tutorials on Cocoa Dev Central, such as http://cocoadevcentral.com/d/learn_objectivec/ . That should help a lot. Also buying a book could be a good idea, like Aaron Hillegass’s excellent Cocoa Programming for Mac OS X ( http://www.amazon.co.uk/Cocoa-Programming-Mac-OS-X/dp/0321503619/ ).
Thanks Matt and thanks again for a great tutorial!
line 36 can have a extra pair of brackets to suppress browser warnings.
not really sure what line 27 does
Can the singleton be synth-ed in another class? (so it can be used in all methods) Or do you need to put the line…
MyManager *sharedManager = [MyManager sharedManager];
..before you deal with any vars in MyManager?
@Consta:
Line 36: Yes, that’s right, add a pair of brackets to silence the compiler.
Line 27: It’s a note to anyone using the singleton that the retain count is very large – it’s not going to get released any time soon.
You can access it by [[MyManager sharedManager] doSomething]; if you want, rather than storing it to a temporary variable first.
Hi Matt, sweet tutorial!
Just a little question, If im using my singleton to download data from a html website and therefore give all my view controllers access to the trimmed string, where do i put my code that trims and downloads? should I create a -(void)CreateData? Or should I put it within the (id) init? Im very new to objective c, sorry if this is a stupid question!
Hello, great tutorial just what i needed. I have a single question about singleton. Should i release a pointer to the sharedManager ?
Service service = [Service sharedManager];
//do something with sharedManager.
[service release];
Best Regards
Morten
@Morten – No. And if you don’t know why, then I suggest you go and read up about memory management. Technically, releasing the singleton will do absolutely nothing, but it’s unneeded code. The whole point of a singleton is that it cannot be released – it’s lifetime is that of the process.
Great work, Matt.
Your initiative helped us save a lot of time!
We have to thank you!
[...] Singleton Classes « Matt Galloway’s iPhone Apps [...]
I am using Singleton pattern in my app to hold data in memory across the app but due to that I am facing some memory crashes.. Like when my application goes in background n keep it there for long time n open it again it crashes….how to manage this with Singleton..
I get a somewhat cryptic warning message on your -(void)release method.
Where the method is defined in my source code:
- (void)release{ }
…i see this warning:
warning: Semantic Issue: Conflicting distributed object modifiers on return type in implementation of ‘release’
If I click on the warning it takes me to the line in NSObject.h declaring the release method:
- (oneway void)release;
…with the warning:
notice: Previous declaration is here
So what is ‘oneway void’? and why is that conflicting with normal ‘void’
Hi Matt,
Thanks a lot for the code.
I stumbled upon [super allocWithZone:NULL] in +(id)sharedManager method. How does it get to know MyManager class size? The message receiver is MyManager superclass, i.e. NSObject rather than MyManager, is not it?
Could you please clarify how it works?
Thank you in advance.
[...] I created a singleton class as described here: http://iphone.galloway.me.uk/iphone-sdktutorials/singleton-classes/ [...]
Very nice! Thanks for posting this code
Yeah, thanks! I was looking for the ARC Singleton conversion! It helped me a lot!
Thanks for sharing!
Hi Matt,
thank you very much for share your code;
I’m new to iOS development and it’s very useful for me to understand how to implement a singleton in ObjC (I often use singletons in my java applications).
I’ve just a problem:
the compiler won’t compile the ARC version of the singleton and returns the following message for the [super dealloc]; call in the dealloc method: “ARC forbids explicit message send of ‘dealloc’”.
I take a look around and I find the following in the Apple documentation: “You cannot explicitly invoke dealloc, or implement or invoke retain, release, retainCount, or autorelease.”
(Transitioning to ARC Release Notes: http://developer.apple.com/library/mac/#releasenotes/ObjectiveC/RN-TransitioningToARC/_index.html)
Did I misunderstood something in your code?
Thank you again.
@ Massimiliano – Sorry about that, I had a slight mistake in the code. I shouldn’t be calling [super dealloc] in dealloc because as you say, when using ARC we’re not supposed to do this ourselves. I’ve fixed the post to show that.
@Matt – Thank you again!
Very good post, usable , simple and easy to understand.
Thank you very much!!!
Hi this looks just what I am after but I am getting a bit lost.
I have created a basic Tab Bar application and then created MyManager.m and h from the above code.
I want to set a value for someProperty in my FirstViewController. I am confused how I would do this.
Do I need to add @property (nonatomic, retain) NSString *someProperty; to my FirstViewController.h and then #import “MyManager.h” and @synthesize someProperty; in FirstViewController.m
I am very new to this so sorry if it is obvious.
Many thanks
@photoboy – It sounds like you probably want to add the property to MyManager, not FirstViewController. What is it that you exactly what to do though?
Thank you very much. Helped me to solve a big problem.
Hi Matt,
Thanks for this article. When I read through your code, this part looked a bit circular:
#pragma mark Singleton Methods
+ (id)sharedManager {
@synchronized(self) {
if(sharedMyManager == nil)
sharedMyManager = [[super allocWithZone:NULL] init];
}
return sharedMyManager;
}
+ (id)allocWithZone:(NSZone *)zone {
return [[self sharedManager] retain];
}
When I retooled my iPhone app to incorporate this code for my singletons, I got a stack overflow error. Should allocWithZone be
+ (id)allocWithZone:(NSZone *)zone {
return [[self init] retain];
}
instead?
Forget my last comment. I wasn’t reading the code correctly. I replaced super in the factory method with the class name, which then does make it circular. Thanks.
Great summary. Really helped me put the singleton pattern into context for iOS.
One question… is there any issue with using a pattern like this to manage async communication with an outside web service? Being that the singleton is not really retained and only used for the intended process, does that process remain open to receive callbacks upon async completion of a process?
Thanks Matt!
Hey, love the Singleton code.
I tried emulating what you wrote in my code (ARC supported) but I’m getting an “Expected ‘;’ at end of declaration list” error on the singleton instantiation/declaration: MyManager *sharedManager = [MyManager sharedManager]; (The error is pointing at the equal’s sign)
I’m definitely not missing any semi-colons, do you have any idea what else might cause that error?
@bearnun – Have you added
#import "MyManager.h"in the code that is usingMyManager? If that’s not it then would you mind pasting a bit of code so I can maybe see what’s going on?Sure! I changed variable names a little to correspond to my code, but Match is “MyManager” basically.
“Match.h”
#import
@interface Match : NSObject {
NSString *meetName;
}
//Corresponding getText from textFields
@property (nonatomic, copy) NSString *meetName;
+ (id)thisMatch;
@end
“Match.m”
#import “Match.h”
static Match *thisISMatch = nil;
@implementation Match
@dynamic meetName;
+ (id)thisMatch {
@synchronized(self) {
if (thisISMatch == nil)
thisISMatch = [[self alloc] init];
}
return thisISMatch;
}
- (id)init {
if (self = [super init]) {
meetName = [[NSString alloc] initWithString:@”Default Property Value”];
}
return self;
}
@end
Then I try to use the code by referencing the singleton in another class’s header file:
Match *thisMatch = [Match thisMatch];
This is the line that is being troublesome. The error I mentioned is on this equal sign.