Proper Singleton Implementation - objective-c

I'm reading through a book trying to brush the dust off of Objective-C, and I ran into this question while reading how to implement a singleton. This is the implementation as they have it in the book:
+ (ClassName *)sharedClass {
static ClassName *sharedClass = nil;
if (!sharedClass) {
sharedClass = [[super allocWithZone:nil] init];
return shared store
}
My question is, why would they set it to nil each time the method is ran, then check if it's nil, which it now obviously is, and create a new instance? That sounds like it defeats the whole purpose of a singleton, to only have one instance of a class. I've noticed a ton of questions related to singleton implementation, but none specific to this aspect of it. Believe me, I combed through before posting.

The static variable is set to nil only for the first time. Once the sharedClass instance is instantiated, you will alway have the same instance whenever you invoke [ClassName sharedClass].
You should use thread-safe pattern to use singleton pattern.
+ (instancetype)shared {
static id shared = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
shared = [[self alloc] init];
});
return sharedInstance;
}
This will prevent possible crashes.

Related

Are my Objective-C singletons thread safe?

I've been reading around and its hard to get a clear feel if I have written a thread safe implementation here.
My getter looks like
+ (MySingleton *)getSingleton
{
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
singleton = [[MySingleton alloc] init];
});
return singleton;
}
And my setter is:
+ (void)updateSingleton:(MySingleton *)newSingleton
{
#syncronized(self) {
singleton = newSingleton;
}
}
No, that isn't thread safe. Your exclusion mechanism between your two modification methods are not the same. dispatch_once has nothing to do with #synchronized in any way.
Beyond that a singleton must never be replaced by definition. A singleton can come into existence at any time and, once it does, it never, ever, goes away.
Also, getSingleton should be sharedInstance or some similar objective-c standard moniker. Methods should never be prepended with get unless they are returning stuff by reference.

Can I make single-instance classes in Objective-C? [duplicate]

This question already has answers here:
Create singleton using GCD's dispatch_once in Objective-C
(10 answers)
Closed 7 years ago.
What I want to create:
I want to make a class that has a shared instance of itself. When I call [someClass sharedInstance];, I want to have it return just that: a shared instance of itself.
The reason is this: I want to have a class in my app that can handle a bunch of methods that I would need to call a bunch of times, or get values of. For example, I want a class that can access motion data using CoreMotion from the data's gyroscope and have it be read correctly in any orientation.
I know, in landscape, the X and Y values are swapped if you're making the update change the Euler angles of a SceneKit camera node.
If I want to make a bunch of scenes, I'd have to create many instances of this motion manager class, and have it load with each scene. That can be avoided with only making one instance of said motion manager, starting it up, and then getting/returning values every so often.
My problem is:
How would I go about coding a class method call so it will return the class's shared instance? I know the method call would be +(instancetype)sharedInstance in the class's .h/.m files, but I don't know how to get it to return said shared instance.
Also, how would I initialize the shared instance?
Edit note: The question it is apparently a duplicate of is NOT a duplicate of this question; that question is about whether or not GCD's dispatch_once is the best way of doing it in iOS 4.0. Most devices nowadays don't use iOS 4.0, and 4.0 is very well obsolete.
Absolutely. This is the singleton pattern I've always used for objective-c
+ (instancetype)sharedManager {
static MyManager *sharedMyManager = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
sharedMyManager = [[self alloc] init];
});
return sharedMyManager;
}
and here's one for if you want your singleton to be achievable and will unwrap the achieved instance if one exists:
+ (instancetype)sharedManager {
static MyManager *sharedMyManager = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
NSArray *archivePathHeader = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *archivePathToDocuments = [archivePathHeader objectAtIndex:0];
NSString *filePathOfArchive = [archivePathToDocuments stringByAppendingPathComponent:#"[FILE NAME]"];
if ([[NSFileManager defaultManager] fileExistsAtPath:filePathOfArchive]) {
sharedMyManager = [NSKeyedUnarchiver unarchiveObjectWithFile:filePathOfArchive];
} else {
sharedMyManager = [[self alloc] init];
}
});
return sharedMyManager;
}
Both of these use the GCD.
you can call them like so:
sharedSettings = [Settings sharedSettings];

Setting static inside its method call (with singleton pattern)

is smth. like this legit? it compiles and looks running ok, but is it ok? (aim setting myself to nil, inside my method)
i mean iam setting myself static to nil, in a method
static MyClass * StaticInstance = nil;
+ (MyClass *) sharedStaticInstance
{
if (StaticInstance == nil) {
StaticInstance = [[MyClass alloc] init];
}
return StaticInstance;
}
- (void) killStaticSelf
{
StaticInstance = nil;
}
and later
[[MyClass sharedStaticInstance] doSmth]; // our static instance is created
[[MyClass sharedStaticInstance] killStaticSelf]; // now its killed inside itself method
[[MyClass sharedStaticInstance] doSmth]; // now it should recreate again
Its having a memory leak.
You should dealloc the StaticInstance first and then you should assign nil to it.
Yes, that's how it's done. I use the sharedStaticInstance often, though I don't usually create a destructor it's probably a good idea, as long as all references to the shared instance in this class pass through sharedStaticInstance first.
EDIT: I just noticed that killStaticSelf is an instance method - it should be a class method I believe, but there shouldn't be any issue either way.
[MyClass killStaticSelf];
Even as the function stack closes, since sending messages to nil doesn't cause issues in Objective-C.
your sharedInstance method is not thread safe so you could get a race condition in this code:
if (StaticInstance == nil) {
StaticInstance = [[MyClass alloc] init];
}
- (void) killStaticSelf
{
StaticInstance = nil;
}
the above code has a leak since you do not provide StaticInstance as a retain property (apparently). You could instead wrap your singleton code in a property but that uses the same static instance.
It's legit, but you need to release the variable before setting it to nil, to avoid memory leaks if you're not using ARC.
Though comprehension of such singleton usage logic is beyond my humble brain abilities.

Singleton in iOS 5?

Hi I had an implementation previous versions of iOS for a singleton as follows:
.h file
#interface CartSingleton : NSObject
{
}
+(CartSingleton *) getSingleton;
.m file
#implementation CartSingleton
static CartSingleton *sharedSingleton = nil;
+(CartSingleton *) getSingleton
{
if (sharedSingleton !=nil)
{
NSLog(#"Cart has already been created.....");
return sharedSingleton;
}
#synchronized(self)
{
if (sharedSingleton == nil)
{
sharedSingleton = [[self alloc]init];
NSLog(#"Created a new Cart");
}
}
return sharedSingleton;
}
//==============================================================================
+(id)alloc
{
#synchronized([CartSingleton class])
{
NSLog(#"inside alloc");
NSAssert(sharedSingleton == nil, #"Attempted to allocate a second instance of a singleton.");
sharedSingleton = [super alloc];
return sharedSingleton;
}
return nil;
}
//==============================================================================
-(id)init
{
self = [super init];
}
However on the web I see people have implemented the Singleton design pattern using this code:
+ (id)sharedInstance
{
static dispatch_once_t pred = 0;
__strong static id _sharedObject = nil;
dispatch_once(&pred, ^{
_sharedObject = [[self alloc] init]; // or some other init method
});
return _sharedObject;
}
Could someone who is experience please guide me.
Im a newbie and thoroughly confused between the old iOS implementation of the Singleton and the new one and which is the correct one?
Thanks a lot
Strictly speaking, you must use:
+ (MySingleton*) instance {
static dispatch_once_t _singletonPredicate;
static MySingleton *_singleton = nil;
dispatch_once(&_singletonPredicate, ^{
_singleton = [[super allocWithZone:nil] init];
});
return _singleton;
}
+ (id) allocWithZone:(NSZone *)zone {
return [self instance];
}
Now you guarantee that one cannot call alloc/init and create another instance.
Explanation: The instance method is at the class level and is your main access method to get a reference to the singleton. The method simply uses the dispatch_once() built-in queue that will only execute a block once. How does the runtime guarantee that the block is only executed once? Using the predicate you supply (of type dispatch_once_t). This low-level call will guarantee that even if there are multiple threads trying to call it, only one succeeds, the others wait until the first one is done and then returns.
The reason we override allocWithZone is because alloc calls allocWithZone passing nil as the zone (for the default zone). To prevent rogue code from allocating and init-ializing another instance we override allocWithZone so that the instance passed back is the already initialized singleton. This prevents one from creating a second instance.
The dispatch_once snippet is functionally identical to other one. You can read about it at http://developer.apple.com/library/mac/#documentation/Darwin/Reference/Manpages/man3/dispatch_once.3.html.
This is what I use for singletons:
+ (MySingleton*) getOne {
static MySingleton* _one = nil;
#synchronized( self ) {
if( _one == nil ) {
_one = [[ MySingleton alloc ] init ];
}
}
return _one;
}
NOTE: In most cases, you do not even need to use #synchronized (but it is safe this way).
A singleton is a special kind of class where only one instance of the class exists for the current process. (In the case of an iPhone app, the one instance is shared across the entire app.) Some examples in UIKit are [UIApplication sharedApplication] (which returns the sole instance of the application itself), and [NSFileManager defaultManager] (which returns the file manager instance). Singletons can be an easy way to share data and common methods across your entire app.
Rather than create instances of the singleton class using alloc/init, you'll call a class method that will return the singleton object. You can name the class method anything, but common practice is to call it sharedName or defaultName.
Please check a link with best answer
:http://www.idev101.com/code/Objective-C/singletons.html

When and where to release a Singleton instance in Objective-C?

I am not sure if i am asking the right question or not.
I have a singleton class as below:
static DBHandler *dbHandler = nil;
+(DBHandler *)sharedDBHandler {
#synchronized(self) {
if(nil == dbHandler) {
dbHandler = [[[self class] alloc] init];
}
}
return dbHandler;
}
When and where to release a Singleton instance in Objective-C ?
Thanks,
Never and Nowhere. Unless in the code that uses the singleton object you retained it for some inexplicable reason.
Most often they are located in static memory which means they are handled differently. See this question:
Objective-C/iPhone Memory Management Static Variables