Singleton in iOS Objective C Doesn't Prevent More Than One Instance

Objective C - Singleton static method overriding doesn't work for multiple subclasses

A common base class for singletons is a contradiction in itself.

What should be obvious is that with your sharedSingleton implementation, there is only one dispatch_once_t token. So the code inside dispatch_once_t will only be executed once in your application. There is also only one static variable for _sharedInstance, so it cannot possibly return two different sharedInstance values.

Don't do this.

Singleton Object in iOS

You can forbid calls of init with such trick:
add - (instancetype)init NS_UNAVAILABLE; definition to your singleton interface.

Instead of [[PhotoManager alloc] init]; use [[[self class] alloc] init];

PhotoManager *sharedManager = [[PhotoManager alloc] init]; won't compile.

There is my example:

@interface SomeSingleton : NSObject

+ (instancetype)sharedInstance;
- (instancetype)init NS_UNAVAILABLE;

@end

@implementation SomeSingleton

+ (instancetype)sharedInstance {
static dispatch_once_t onceToken;
static SomeSingleton *instance;
dispatch_once(&onceToken, ^{
instance = [[[self class] alloc] init];
});

return instance;
}

- (instancetype)init {
self = [super init];

return self;
}

@end

As result SomeSingleton *s1 = [SomeSingleton sharedInstance]; works, but SomeSingleton *s2 = [[SomeSingleton alloc] init]; leads to the compile error.

What is the best practice to prevent an instance from init() in a Singleton class in Swift

The way that you have suggested is the way that I always implemented it.

public class Singleton
{
static public let sharedInstance = Singleton();

private init()
{

}
}

It's the cleanest solution for a Singleton pattern that I've ever found. Now that in Swift 2 you can specify accessibility it does actually prevent you from calling something like:

var mySingleton = Singleton();

Doing so results in a compile time error:

'Singleton' cannot be constructed because it has no accessible initializers

How do I implement an Objective-C singleton that is compatible with ARC?

In exactly the same way that you (should) have been doing it already:

+ (instancetype)sharedInstance
{
static MyClass *sharedInstance = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
sharedInstance = [[MyClass alloc] init];
// Do any other initialisation stuff here
});
return sharedInstance;
}

What should my Objective-C singleton look like?

Another option is to use the +(void)initialize method. From the documentation:

The runtime sends initialize to each class in a program exactly one time just before the class, or any class that inherits from it, is sent its first message from within the program. (Thus the method may never be invoked if the class is not used.) The runtime sends the initialize message to classes in a thread-safe manner. Superclasses receive this message before their subclasses.

So you could do something akin to this:

static MySingleton *sharedSingleton;

+ (void)initialize
{
static BOOL initialized = NO;
if(!initialized)
{
initialized = YES;
sharedSingleton = [[MySingleton alloc] init];
}
}

Correct Singleton Pattern Objective C (iOS)?

Keep it simple:

+(instancetype)sharedInstance
{
static dispatch_once_t pred;
static id sharedInstance = nil;
dispatch_once(&pred, ^{
sharedInstance = [[self alloc] init];
});
return sharedInstance;
}

- (void)dealloc
{
// implement -dealloc & remove abort() when refactoring for
// non-singleton use.
abort();
}

That is it. Overriding retain, release, retainCount and the rest is just hiding bugs and adding a bunch of lines of unnecessary code. Every line of code is a bug waiting to happen. In reality, if you are causing dealloc to be called on your shared instance, you have a very serious bug in your app. That bug should be fixed, not hidden.

This approach also lends itself to refactoring to support non-singleton usage modes. Pretty much every singleton that survives beyond a few releases will eventually be refactored into a non-singleton form. Some (like NSFileManager) continue to support a singleton mode while also supporting arbitrary instantiation.

Note that the above also "just works" in ARC.

In Objective-C, is there any reason not to reference `self` instead of a singleton within the same class of the singleton?

It is both unnecessary and bad.

in theory there only ever will be one

From the description you have a shared instance model, not a singleton model, there could be more than one. Debugging would get messy quickly due to unexpected object interactions.

And while not significant the code is also larger and slower.

So the code takes a risk, introduces potential bugs, and all for no gain.



Related Topics



Leave a reply



Submit