How to create Singleton in iPhone?
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.
Note: A singleton does not need to be explicitly
allocated or initialized (the alloc and init methods will be called automatically on first
access) but you can still implement the default init method if you want to perform initialization.
Advantages of a singleton
A
well-designed singleton is a discrete, self-managing object that manages a
specific role within your program.
Variables
hung off the Application delegate should be limited to objects that relate to
the Application delegate in some way. A singleton should be entirely focussed
on its own specific role and responsibilities. To avoid the anti-pattern known
as "coupling" your singletons should have zero (or practically zero)
connections to the rest of your program — they should be stand-alone little
pockets of functionality.
Search
the Mac OS X Reference in XCode for methods that begin with "shared"
to see the ways in which Apple use singletons to create "manager"
objects which allow you to get, set and manipulate entities that exist only
once in a program.
Also,
since the singleton is accessed through a method, there is some abstraction
around the specific implementation — you could move from a true singleton to a
per-thread based implementation if you needed, without changing the external
interface.
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!");
}