Reputation: 519
In Objective-C, how to write a singleton with ARC? In ARC, it is not allowed to overwrite the release, autorelease, retain, retainCount methods, how to avoid a object to be released? I know without ARC, a classic singleton would like below:
@interface SingletonObject
+ (SingletonObject*)sharedObject;
@end
SingletonObject *sharedObj;
@implementation SingletonObject
+ (id)allocWithZone:(NSZone *)zone
{
if (sharedObj == nil) {
//So the code [[SingletonObject alloc] init] is equal with [SingletonObject sharedObject]
sharedObj = [super allocWithZone:zone];
}
return sharedObj;
}
+ (void)initialize
{
if (self == [SingletonObject class]) {
sharedObj = [[SingletonObject alloc] init];
}
}
+ (SingletonObject*)sharedObject
{
return sharedObj;
}
- (id)retain
{
return self;
}
- (unsigned)retainCount
{
return UINT_MAX; //denotes an object that cannot be released
}
- (oneway void)release
{
//do nothing
}
- (id)autorelease
{
return self;
}
- (id)init {
self = [super init];
if (self) {
//...
}
return self;
}
@end
Is it safe to just remove the retain, retainCount, release, autorelease methods? Thanks!
Upvotes: 1
Views: 762
Reputation: 162712
You only need one method to implement a class that supports the singleton pattern:
+ (instancetype)sharedInstance
{
static id _sharedInstance = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
_sharedInstance = [[self alloc] init];
});
return _sharedInstance;
}
Copy/paste that into any class and it'll have a shared instance. Any code beyond that is just added complexity that really isn't necessary. I'll sometimes add:
- (void)dealloc
{
*(char*)0x42 = 'b';
// no super, ARC all the way
}
That'll cause a very specific crash if my shared instance is ever deallocated due to a bug. (Yes, hex 0x42 is not 42, but it leaves a nice 0x000000042 in a register in the crash log, making it immediately identifiable what happened.)
Upvotes: 8
Reputation: 28242
Yes.
-sharedObject
should be +sharedObject
, though (class method). Just make sure you always use that.
Upvotes: 0