Should I use +load to generate a singleton? - objective-c

I'm writing a singleton class, and I usually do this:
#interface MySingleton
+ (instancetype) instance;
#end
#implementation MySingleton
+ (instancetype) instance {
static MySingleton *instance;
if (!instance) {
instance = [MySingleton new];
}
return instance;
}
#end
But I recently considered this pattern:
#interface MySingleton
+ (instancetype) instance;
#end
#implementation MySingleton
static MySingleton *instance;
+ (void) load {
instance = [MySingleton new];
}
+ (instancetype) instance {
return instance;
}
#end
I find this more elegant and easier to understand, but this will be my first time using +load. Are there any pitfalls that I might not expect? Is there any reason this would be a bad idea?

+load has been deprecated/removed for Swift code. While existing ObjC code will still execute it (even if called from Swift), new code should not rely on it. The dispatch_once approach that #gnasher729 references is strongly preferred, and has the benefit of being lazy (while +load slows down launch; dispatch_once doesn't force construction until first usage). The dispatch_once Singleton is even a built-in code-snippet in Xcode. Apple provides the recommended implementation in Adopting Cocoa Design Patterns.
+ (instancetype)sharedInstance {
static id _sharedInstance = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
_sharedInstance = [[self alloc] init];
});
return _sharedInstance;
}
(Or in Swift)
class Singleton {
static let sharedInstance = Singleton()
}
The naming sharedInstance (or better, sharedFoo for the class Foo) is preferred over instance. See +[NSURLSesssion sharedSession], etc. This captures the real nature of singleton in ObjC, which is not really Singleton. There is just a single well-known instance. You are usually free to instantiate additional instances using +new or +alloc. +instance sounds like it does the same thing as +new, create a fresh instance. +sharedInstance makes it clear that this is an instance shared by other callers.
As a side-note, I'd mention that many in the ObjC community have been gradually moving away from singletons in recent years because of the difficulties they create in testing, their creation of global mutable state, and general inflexibility. Manual dependency injection (i.e. just setting properties or passing parameters, not complex DI frameworks) has been growing in favor. This is far from universal, and I'm not claiming Singleton is an anti-pattern in ObjC, but I do encourage you to avoid Singleton when it is not a huge benefit. For years it was my go-to solution to many problems, but times and patterns change.

There is a widely used pattern to create singletons using dispatch_once. There is absolutely no reason whatsoever why anyone would create a singleton in any different way. Instead you want to use some deeply obscure technology (which for example doesn't work once you switch to Swift).
By the way, try calling some class method to configure your singleton before it is created. Doesn't work with +load.
By the way, your "usual way" isn't thread safe.

Related

Difference between Singleton class and singleton method?

I have one question.
What is the difference between singleton class and singleton method. I have created shared instance method, if I use alloc method, it will create new instance or not?
Thanks in advance
The "singleton pattern" (or a "singleton class" or just "singleton") is simply any class for which you are only allowed a single instance.
A "singleton method" would refer to the method that one writes to access the instance. (Nowadays, in Swift and Objective-C, the public interface would declare a property to access the singleton, not a method, but the idea is the same.)
Conventionally the "singleton pattern" refers to a class that simply would not permit the creation of additional instances. But it should be noted that the term "singleton" is sometimes used more loosely in those cases where there exists a single shared instance, but for which you may actually permit creation of your own instances, too. An example of that would be NSURLSession, whose sharedSession property is referred to as a "singleton" in the Apple documentation, but one is still permitted to create ones' own custom NSURLSession sessions.
Bottom line, whether you design your singleton in such a manner that you can or cannot instantiate additional instances is a question of the design of your class. (Many assiduously insist that this is the very meaning of "singleton". I'm not going to participate in that debate.) In many cases, we explicitly want to want to prevent the accidental creation instances. In other (more rare) cases, though, you may want to permit both a singleton as well as the ability to create additional instances. It's just a question of the intent of the singleton's class.
Note, your question was originally tagged objective-c. An Objective-C implementation might look as follows:
NS_ASSUME_NONNULL_BEGIN
#interface Foo : NSObject
#property (class, strong, readonly) Foo *sharedFoo;
- (instancetype)init __attribute__((unavailable("Use +[Foo sharedFoo] instead")));
+ (instancetype)new __attribute__((unavailable("Use +[Foo sharedFoo] instead")));
#end
NS_ASSUME_NONNULL_END
And
#implementation Foo
+ (Foo *)sharedFoo {
static Foo *sharedFoo = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
sharedFoo = [[self alloc] init];
});
return sharedFoo;
}
- (id)init {
if ((self = [super init])) {
// do additional initialization here
}
return self;
}
#end
Note:
Nowadays one would generally define the singleton to be accessed through a #property in the public interface, not as a method. This property would be declared as class and readonly, and you would then manually implement the getter accessor method for that property.
By defining this public interface to be a property rather than a method, should you ever interface with this object via Swift, you will be accessing it using patterns more common in Swift. You don't have to define it as a property, but you generally would.
Note that I defined this property to be sharedFoo, rather than sharedInstance or sharedManager. By calling it sharedFoo, when you bridge this code with Swift, it will automatically be exposed as shared, the more concise name that Swift, as a matter of convention, uses for its singletons and other shared instances.
In this case I have declared init and new as unavailable. This will prevent developers from accidentally instantiating additional instances. Again, this is a question of the purpose of the singleton.
If you look at singletons (or other shared instances) throughout the Cocoa API, you'll see that Apple has transitioned to this property approach.

Using a Singleton as property of another class vs calling it in every method

I'm asking this for Objective-C because I use it there, but it might apply for all other languages:
-is it a bad thing to have a reference of a single to a Obj-C property?
-Would it be better to call the shared instance in every method?
More precise: I have a singleton class that I can call by using [MySingleton sharedInstance];
I need values of that singleton like 50 times in another class MySecondClass So I created a Obj-C property
#property (nonatomic, strong) MySingleton *mySingletonProperty;
and lazily initialize that property once in MySecondClass by calling
if(!self.mySingletonProperty)
{
self.mySingletonProperty = [MySingleton sharedInstance];
}
A friend of mine told me this would be a bad idea, and it would be better not to use a singleton to instanciate a property. The right way would be to call [MySingleton sharedInstance]; in every method of MySecondClass and assign it to a local variable.
Is that correct? And why? Thread safety is not an issue.
(Please don't discuss if it's a bad idea using a singleton in general here - thanks:-)
The argument I usually see against repeatedly calling [SingletonClass sharedSingleton] is message-passing (function call) overhead. In that case, stashing a reference to your singleton in a property has the same problem -- calling self.singleton all the time is the same number of function calls as calling [SingletonClass sharedSingleton].
That's not a great argument, though, because such overhead has negligible performance impact.
Instead, I'd be concerned about the semantic implications of using a property. While it's generally an assumption of the singleton pattern that there is only one instance of the singleton class over the lifetime of your app, nothing about the "standard" singleton interface guarantees that. If you don't own the singleton class, you may violate its design assumptions by retaining it over the lifetime of some other object with a strong property. If you do own that class, keeping a strong reference to it adds extra design constraints that may (however unlikely) cause problems for you later on.
In summary, I'd give the following advice. If you have code that looks like this:
- someMethod {
[[SingletonClass sharedSingleton] doSomething];
}
- someOtherMethod {
[[SingletonClass sharedSingleton] doSomethingElse];
}
There's nothing wrong with it. (If you really want to save yourself some typing, maybe a local preprocessor macro for [SingletonClass sharedSingleton] is in order.)
If you have code like this:
- someMethod {
[[SingletonClass sharedSingleton] doSomething];
[[SingletonClass sharedSingleton] doSomethingElse];
[[SingletonClass sharedSingleton] doSomeOtherThing];
[[SingletonClass sharedSingleton] doYetAnotherThing];
}
Then you can save yourself a bit of typing (and trivial performance cost) without semantic changes by stashing it in a local variable:
- someMethod {
SingletonClass *singleton = [SingletonClass sharedSingleton];
[singleton doSomething];
[singleton doSomethingElse];
[singleton doSomeOtherThing];
[singleton doYetAnotherThing];
}
If you still need a singleton there is nothing wrong with keeping a reference to it. But why do you keep the reference as a property? My advice is to create an internal variable:
#interface MySecondClass : NSObject {
// ...
MySingleton *mySingletonInstanse;
}
// ...
#end

objective c singleton dispatch_once implementation is better?

I have seen many people suggesting to use dispatch_once to do the singleton:
+(MyClass *)singleton {
static dispatch_once_t pred;
static MyClass *shared = nil;
dispatch_once(&pred, ^{
shared = [[MyClass alloc] init];
});
return shared;
}
Why is this better when it doesn't really support true singleton, and people can still use init to create an instance and even do a release on the sharedInstance?
Apple's way is preventing all those cases
http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/CocoaFundamentals/CocoaObjects/CocoaObjects.html
I know it is not thread-safe, but I think it is easy to put a synchronize block there to make it thread-safe.
Why not just combine the two?
Use the function you listed instead of Apple's + (MyGizmoClass*)sharedManager function, but implement all of the allocWithZone, copyWithZone, retain, retainCount, release, and autorelease overrides.
Lots more discussion here: What should my Objective-C singleton look like?
If you want it to be a singleton, and you are worried about what happens if you call alloc/init: Don't do it! Simple as that.
There are cases, like NSFileManager, where you have both a singleton [NSFileManager defaultManager] but you can also have individual NSFileManager* objects. So this achieves it quite easily.

singleton in objective c

I saw a singleton example on objective-c book. However, I don't know if there is difference of meaning of 'singleton' definition between objective-c and other langs. Can this [[SingletonClass alloc] init] still be used to create a new object? If yes, how to guarantee there is only one object in the memory?
#import "SingletonClass.h"
#implementation SingletonClass
static SingletonClass *sharedInstance = nil;
// Get the shared instance and create it if necessary.
+ (SingletonClass*)sharedInstance {
if (sharedInstance == nil) {
sharedInstance = [[super allocWithZone:NULL] init];
}
return sharedInstance;
}
// We can still have a regular init method, that will get called the first time the Singleton is used.
- (id)init
{
self = [super init];
if (self) {
// Work your initialising magic here as you normally would
}
return self;
}
If you want a true singleton, i.e. an object that can be instantiated only once, take a look at Apple's documentation: Creating a Singleton Instance.
Basically, the idea is to override a number of methods related to allocating and managing objects: +allocWithZone (which is called by +alloc), -retain, -release, -copyWithZone, etc., so that it becomes quite difficult to create more than one instance of your singleton class. (It's still possible to create a second instance by calling the runtime directly, but this should be enough to get the point across.)
Pretty much every blogger who has ever written about Objective-C in any capacity has offered an opinion on how to implement singletons. Many of those opinions seem pretty good, and most of them are fairly similar. It's clear that Dave DeLong knows what he's talking about, and his piece on singletons is short, sweet, and gets straight to the point.
I don't know if there is difference of meaning of 'singleton' definition between objective-c and other langs.
It follows the common definition of languages derived from C.
Can this [[SingletonClass alloc] init] still be used to create a new object?
Yes
If yes, how to guarantee there is only one object in the memory?
Avoid enforcing the pattern (e.g. do not force it to be a singleton). Just make a normal object. Then if you really want only one instance, create an instance and save it someplace for reuse (your app delegate is one typical place for this, because it is typically created once per execution).
In practice, most (>95%) ObjC singleton implementations i've seen in the wild are used for the wrong reasons, and would have been better or as good as normal objects.
Every solution linked in the answers so far has (at minimum) subtle problems, dangers, or undesirable side-effects.
There is no language support for singletons, but you can do it by hand. Look at the singleton example here. It doesn't look like it is thread-safe, though. I would allocate the object in +initialize instead of +sharedManager.
You can create a singleton in Objective-C by doing the following:
+(MyAPI *)shared {
static dispatch_once_t queue;
static MyAPI *singleton = nil;
dispatch_once(&queue, ^{
singleton = [[MyAPI alloc] init];
});
return singleton;
}
This will also ensure that it is thread safe. Without using the dispatch_once you run the risk of multiple threads trying to access it at the same time when one is in the middle of allocating it, and the other is trying to use it.
Singleton class is used to save the data for use anywhere in app.
//SingletonObject
#define saveDataSingletonObject ((SaveDataSingleton*)[SaveDataSingleton sharedManager])
#interface SaveDataSingleton : NSObject
#property (nonatomic,strong) NSMutableArray *DataArr;
+ (id)sharedManager;
-(void)clearAllSaveData;
#end
#implementation SaveDataSingleton
#synthesize DataArr;
+ (id)sharedManager {
static SaveDataSingleton *sharedManager;
if(!sharedManager) {
#synchronized(sharedManager) {
sharedManager = [SaveDataSingleton new];
}
}
return sharedManager;
}
-(void)clearAllSaveData{
DataArr=nil;
}
- (id)init {
if (self = [super init]) {
DataArr = [[NSMutableArray alloc]init];
}
return self;
}
// using setter getter save and retrieve data
+(void)setDataArr:(NSMutableArray *)Dataarr
{
self.DataArr = [[NSMutableArray alloc]initWithArray:Dataarr];
}
+(NSMutableArray *)DataArr
{
return self.DataArr;
}
#end
Save and Retrieve data // Use singleton Object
// save data using setter function.
[saveDataSingletonObject setDataArr:Array];
//fetch data using getter function.
NSArray *arr=[saveDataSingletonObject DataArr];

Singleton or Class methods [duplicate]

This question already has answers here:
What does #synchronized() do as a singleton method in objective C?
(6 answers)
Closed 3 years ago.
After reading the responses to a question about singletons in Objective C it appears that each solution makes some tradeoff in regards to threading in the instance accessor. i.e.
#synchronized(self)
{
if (sharedInstance == nil)
sharedInstance = [[MySingleton alloc] init];
}
return sharedInstance;
This essentially single-threads access to the singleton, and if it's something that's used frequently in an operation, seems like something that could cause threads to unnecessarily contend.
What's the downside to simply using the class object as the singleton instance, and exposing functionality via class methods, i.e.
#interface MySingleton : NSObject {
}
+ (void)doSomething;
#end
#implementation MySingleton
+ (void)initialize {
//do some setup if necessary
}
+ (void)doSomething {
//do something
}
#end
In this way we avoid doing the lock + check every time we want to reference the singleton object and we can also eliminate having to store it in a local or method ivar.
This approach also lets the runtime guarantee that only one instance (the Class object) exists in the system at any given time.
EDIT
There's more here than just threading, with a traditional singleton you usually write code like this:
MySingleton *instance = [MySingleton getSharedInstance];
NSObject *someResult = [instance getResult];
//or
if (instance.someProperty) {
//do something
}
However if your singleton is a class instance, you essentially eliminate the need call getSharedInstance all the time. Consider this code:
NSObject *someResult = [MySingleton getResult];
//or
if ([MySingleton someProperty]) {
//do something
}
I hear the point that you have to store your data in file local static variables, or in global variables (yuck). But it's really not all that different from a traditional singleton with the exception that you lose Objective-C 2.0 properties (instead you have to use traditional accessor methods).
Here's one key tradeoff for me that seems like a win. In a traditional singleton you end up overriding -copyWithZone, +allocWithZone, -retain, -retainCount, -release and -autorelease if you really want to get things right.
This seems like an awful lot of work to do every time you want to write a simple Singleton object (they happen to be pretty useful). So why not simply just replace it with this:
#implementation MySingleton
+ (void)initialize {
//do your setup
}
- (id)init {
NSAssert(NO, #"You should read the documentation on singletons.");
}
#end
It's a lot lighter in terms of code, and unless your consumers are really sneaky they won't ever create two instances.
Get to the point already
My question is really this:
Is there any drawback to using the Class object as the instance of your singleton?
It seems like you can take all the same steps in terms of threadsafety, memory efficiency etc. without having to remember to override so many methods and accessors or litter your code with instance checks.
With iOS 4.0 or later, by far the best solution is to just use dispatch_once, as in
+ (id)sharedInstance {
static dispatch_once_t predicate;
dispatch_once(&predicate, ^{
sharedInstance = [[MyClass alloc] init];
});
return sharedInstance;
}
You may also want to consider using a single dispatch_queue to serialize access to the internals of a class. If all your public methods just run a block on the same dispatch_queue then you won't have to worry about concurrency issues.
This is my first post on Stack Overflow... (so prepare for stupidity)
I think there is a hybrid solution that might be useful.
I want to set and get (global) values out of a singleton class without having calling "getSharedInstance". I'd want the code to look like this...
frameRate = Singleton.frameRate;
Singleton.frameRate = 42;
To achieve this, each variable we need to store in the singleton has a getter and setter class method. The class method then goes to an instance to store the data in an ivar. The instance isn't directly accessed by the main program.
The getter looks like this:
+ (int) frameRate
{
return [[Singleton instance] ivarFrameRate];
}
The (ugly) instance call is hidden inside the class code.
By calling the instance method here, the class method will automatically instantiate an object when first used. Once the singleton is instantiated, the instance stores ivars conventionally. Here, I am prefixing with "ivar" make the ivar explicit.
#property int ivarFrameRate;
and
#synthesize ivarFrameRate;
This automatically creates conventional getter (and setter) methods to access the ivar.
(edit - here is a complete example)
// Singleton.h
#import <Foundation/Foundation.h>
#interface Singleton : NSObject
{
float ivarFrameRate
}
#property float ivarFrameRate;
- (id) init;
+ (Singleton *) instance;
+ (float) frameRate;
+ (void) setFrameRate:(float)fr;
#end
and
// Singleton.m
#import "Singleton.h"
#implementation Singleton
#synthesize ivarFrameRate;
static Singleton* gInstance = NULL;
+ (Singleton*)instance
{
#synchronized(self)
{
if (gInstance == NULL)
gInstance = [[self alloc] init];
}
return(gInstance);
}
- (id)init
{
self = [super init];
return self;
}
+ (float) frameRate
{
return [[Singleton instance] ivarFrameRate];
}
+ (void) setFrameRate:(float)fr;
{
[[Singleton instance] setIvarFrameRate:fr];
}
This is fine, but still just changes your circumstances rather than fixes your problems. Unless you don't have any actual data tied to your singleton, in which case this will work just fine. Anytime you access central data you will need to properly make it thread-safe.
Additionally, without some kind of iVar I don't know of a way to store data (that is intended) directly in a class.
In the example above I would code it in this way, getting the same result as you are proposing and only taking the performance hit if we are creating/re-creating the singleton:
if (sharedInstance)
return sharedInstance;
#synchronized(self)
{
if (sharedInstance == nil)
sharedInstance = [[MySingleton alloc] init];
}
return sharedInstance;
Keep in mind that either way, if you are accessing data that is potentially changing on different threads then you'll have to make that code thread-safe anyway, either with very careful planning or using code to ensure there are no problems. I'd recommend a mix, but when in doubt the latter when at all possible. =)
If you use a class as your singleton, the only way to store data would be to use static file variables and global variables. If you are going to go so far that you make a class you don't plan to instantiate, you might as well just use standard C functions:
void doSomething(void);
void doSomething() {
//do something
}