I've been reading a lot of threads and blog articles about how to implement a singleton in objective-c, several of them maybe being a bit deprecated (year 2010 or earlier), and it seems like people have different opinions regarding this issue... Does Apple have documentation about implementing a singleton? I couldn't find it. If so, could somebody tell me where?
I need a singleton for a class that has some both public and private variables. Currently, this is the implementation I have for such class:
@interface MySingleton ()
@property (strong, nonatomic) NSString *state;
@end
@implementation MySingleton
@synthesize state = _state;
@synthesize count = _count;
static MySingleton *sharedObject = nil;
+ (MySingleton *)sharedInstance
{
static dispatch_once_t _singletonPredicate;
dispatch_once(&_singletonPredicate, ^{
sharedObject = [[super allocWithZone:nil] init];
});
return sharedObject;
}
+ (id)allocWithZone:(NSZone *)zone
{
return [self sharedInstance];
}
Should be this the recommended way? And how should I initialize the instance variables, public and private?
Another issue I'd like to make clear about singleton is: will this generate a memory leak? Is the use of singletons actually recommended in iOS?
Thanks
The above is correct, along with @miho's comment about includng the static object inside of the sharedInstance method. But there is no reason to override +allocWithZone:
. Singletons in ObjC are generally "shared," not forced. You're free to create other instances of a "singleton." If it's illegal to create other instances, then you should make init
perform an NSAssert
rather than fooling the caller in +allocWithZone:
. If your singleton is mutable (and most are), you absolutely should not override +allocWithZone:
this way.
Another issue I'd like to make clear about singleton is: will this generate a memory leak?
No. This object will never be released, but it will always be accessible. That is not a leak.
Is the use of singletons actually recommended in iOS?
Yes, and it is a very common pattern, used all over the Cocoa frameworks. That said, there are various other patterns that have started to recently become somewhat popular among developers. Dependency Injection is getting some interest, though I don't see it in practice very often. Reducing your reliance on singletons can improve testability, and I have been experimenting recently with how to eliminate some of them in my code with some success. But they have a long, proud history in Cocoa, and I do not consider them a problem.
EDIT: you have one actual bug in your code. You should be calling [[self alloc] init]
, not [[super alloc] init]
. There's no reason to ever call +allocWithZone:
, just use +alloc
. (The time when ...WithZone:
methods were useful has long passed.)