Hang
Hang

Reputation: 519

Upgrade an existing singleton to ARC

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

Answers (2)

bbum
bbum

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

Wevah
Wevah

Reputation: 28242

Yes.

-sharedObject should be +sharedObject, though (class method). Just make sure you always use that.

Upvotes: 0

Related Questions