What Is the Use of Singleton Class in Objective-C

How to create singleton class in objective C

Okay appDev, you will probably find quite a few different techniques to do this on the web. However, for iOS app development, I think the most convenient way is to do the following:

  • Write your method(s) for getting the singleton object. (Recommendation: use dispatch_once thread and GCD for this).

  • Wrap your method(s) in a macro and add it to your $Project$-Prefix.pch file.

  • Call the one line macro whenever you need singleton object for a class.

Example:

CommonMacros.h:

#define SINGLETON_FOR_CLASS(classname)
+ (id) shared##classname {
static dispatch_once_t pred = 0;
static id _sharedObject = nil;
dispatch_once(&pred, ^{
_sharedObject = [[self alloc] init];
});
return _sharedObject;
}

YourProject-Prefix.pch:

...
#import "CommonMacros.h"
...

YourSingletonClass.m:

...
SINGLETON_FOR_CLASS(YourSingletonClass)
...

What do we mean by singleton class in objective c? Is it similar to nonatomic property or not?

The Main similarity between them is both are THREAD-SAFE

Check these links for a good idea of singleton classes

http://www.galloway.me.uk/tutorials/singleton-classes/

http://getsetgames.com/2009/08/30/the-objective-c-singleton/

https://www.youtube.com/watch?v=FTfEN8KQPK8 (Example video)

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.

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;
}

The use of singleton class in objective c and swift

To me it seems you do not need a singleton at all. I suggest you would be best of redesigning the architecture to have a user class that can store the information you are needing (and more if you finds the need in the future).

Then you could either pass that user object around between the view controllers as they need or perhaps easier define a currentUser property for the app delegate class.

That way each view controller can obtain the app delegate from the NSApp global reference to the application object and then get the current user object from there. With this pattern the app delegate acts as the globally accessible singleton you need without any need to manage it yourself.

Objective-C: Use singleton vs. use class as an object?

I have been thinking about the same thing and I think I have an answer for you.

It depends on what you need to do with it. Neither is necessarily more "correct".

Read on if you want the details of how I came to my conclusion or scroll down to the tl;dr section.

As you said, it would appear (externally) less cumbersome to access the singleton to have the class manage the singleton for you. Essentially you would do this by replacing the singleton's factory method with an initializer method. Looking at Apple's documentation on this you can see where they show a "shared" method that acts as the factory to produce the singleton upon demand.

static MyGizmoClass *sharedGizmoManager = nil;

+ (MyGizmoClass*)sharedManager
{
if (sharedGizmoManager == nil) {
sharedGizmoManager = [[super allocWithZone:NULL] init];
}
return sharedGizmoManager;
}

Instead of doing this you could replace the method with a void initializer like so:

+ (void)initializeMyGizmo
{
if (sharedGizmoManager == nil) {
sharedGizmoManager = [[super allocWithZone:NULL] init];
}
// whatever else needs to be done to the singleton to initialize it
}

and then ONLY ever use class methods and allow the MyGizmoClass to manage updates to the singleton like [MyGizmoClass setGizmoName:@"Gadget"].

NOTE: In this scenario it would be confusing to someone looking at the .h file to see properties, in which case they may come to the conclusion that they should create an instance of the object themselves, or be able to have access to the singleton in some form or fashion. So if you were to go the route of encapsulating access to the singleton it would not be wise to use public variables.

To that point:

If you do limit access to solely through the class itself you lose any getters and setters or other free things that come along with properties. This means that if MyGizmoClass were to have as part of it's model an NSString *gizmoName you would be forced to create custom getters and setters for this "property" and keep it either as an ivar or property in an interface extension in the .m file (i.e. private) of the singleton class, or as an adjacent static variable.

So this begs the question (and is what got me pondering in the first place), should we even include the line static MyGizmoClass *sharedGizmoManager = nil; at all or can we nix the internal interface extension altogether and replace any possible ivars or properties that we want to limit access to with static implementations in the implementation?

I answered that already...

It depends on what you need to do with it.

tl;dr

First Scenario

If you ever (even the slightest chance) need to subclass your
TextureManager or could create multiple instances of it (making it
no longer a singleton) it would be better to stick to the regular
Apple convention for a singleton.

This includes multiple "singletons" wherein you might have several
TextureManagers preconfigured with different settings.

In this case you would use properties as you need them (publicly or
privately) as well as ivars. You could also use a mix of ivars and
statics but you would still always need to have a static instance of
your TextureManager inside of the TextureManager implementation.

Second Scenario

If you ONLY will ever need ONE instance of the TextureManager and it will run completely standalone with no intermixing further down the line then you could completely remove the static instance of your class within the implementation in the .m file and replace ivars and properties with static variables within that implementation.

This can be useful if you are storing off properties or settings in CoreData and only need them for configuration.

Just remember in this case you will have to create all getters and setters for the static variables and will only be able to access them using class methods (but that's sorta the point).

Other Interesting Stuff

This answer offers an interesting solution to the question of when and how to call the "initializer" method or create the singleton. This can be used with each scenario to either initialize the singleton in the first scenario, or preload defaults into the class-level statics in the second scenario.

If you want to stick with a static singleton in the implementation you might look at this article to give you a better idea at the true "global scope" of your singleton.

Static Class vs Singleton

You're pissing off no Objective-C gods with a class like that. Actually, Apple recommends to use that pattern in some cases (I think they mentioned this in one of the ARC session videos, where they discussed common design patterns and how to implement them using ARC).

In other cases, where you can have multiple instances of a class, but want a default one, you'll of course have to use the shared instance approach.



Related Topics



Leave a reply



Submit