Usage of dispatch_once - ios

I understand that dispatch_once is something that is equivalent to a static variable and that the piece of code inside dispatch_once is executed only once throughout the application.
I am going through a huge code base and came across something like this
+ (DBHelper *)sharedInstance {
static DBHelper *sharedDBHelper = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
sharedDBHelper = [[super alloc] initUniqueInstance];
});
return sharedDBHelper;
}
DBHelper.sharedInstance is used to get an object and is used in a lot of places ot generate objects.
I'm confused as to why dispatch_once is being used here since that would mean you could have only one object of the class?

This is the standard pattern for a shared instance, otherwise known as a faux singleton.
In many cases programmers choose to use a single object that can be easily accessed from any part of an application - by calling a static method which returns back a reference to the shared object, i.e. sharedInstance in your example - as a means to provide communication/shared data between otherwise independent parts of the application.
It is a faux singleton pattern as it does not prevent other instances of the same type - DBHelper in your example - from being created. A true singleton model is one in which only a single instance of the type can ever be created. (Apple used to have sample code showing how to create true singletons, but it was never updated for the post-ARC world, for more details on that including an ARC version see this answer.)
HTH

It's a singleton (a design pattern). You only need one instance of the class instantiated, so that's all you create.

Related

Objective C - Creating singleton using shared instance

I have doubts regarding the creation of singleton class in Objective-C/iOS.
Where ever I see the trick to create a singleton class in objective-C is this code
+ (id)sharedManager {
static MyManager *sharedMyManager = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
sharedMyManager = [[self alloc] init];
});
return sharedMyManager;
}
Whenever I call [MyManager sharedManager] of course I get the same address. However, I can also write [MyManager new] in which case the address is different.
1.Isn't the concept of singleton class is that it restricts the instantiation of a class to one object?
2.If we can create another object its not a singleton anymore, is it?
In my iOS app I tried [UIApplication new]. I got an exception in runtime. Now this I get. You cannot make another instance of UIApplication since its a singleton class.
So why the use of shared instance considered to be the way of creating a singleton class or have I got this all wrong?
The sharedManager is the convenience method you'd use to access the singleton instance. While this doesn't guarantee that there will be only one instance of that manager over the app, if everyone is using sharedManager then there will practically exist only one instance of that manager.
This kind of singletons are singletons by convenience, not by implementation. You should use them, for multiple reasons:
you can unit test them, by calling alloc init in your unit tests and making use of that brand new allocated object
it makes your life easier if decide to later refactor the manager and no longer use it as a singleton if you consider it from the begging like a regular object to work with
Of-course, you can make a singleton by-the-book by overriding the init and allocWithZone: to either return the only instance or by raising an exception, however I'm not sure they'd worth the effort.
There's a very good tech talk regarding singletons held by Misko Hevery in the Google clean code talks playlist, the link to the video: here. This kind of singletons are referred as lower case S singletons, not capital S ones in the video, and Misko explains very well why they are preferred.
It doesn't break singleton concept. You choose your way to implement what you want. If you want to create only singleton instance, you can make run error by override init function:
[NSException exceptionWithName:NSInternalInconsistencyException
reason:#"bla bla bla..." userInfo:nil];
or
you can override it to force return to shared instance.
Of course, you can. But it not recommend if you are using singleton.
Objective-C uses a pragmatic approach. Your +sharedManager method returns a singleton. If someone is stupid enough to call [SingletonClass new] or [[SingletonClass alloc] init], that's their problem. They'll get what they deserve. There is no reason to prevent people from shooting themselves in the foot if that is what they want to do.
There are millions of programming errors that people can make and that the developer of a class or the compiler cannot prevent. No point wasting effort on preventing this particular error.

What is the alternative way for Singleton

I have a single ton which is working fine, but i don't want to use singleton instead any alternative best way
find my code for reference
Myclass.h
+ (instancetype)shareInformation;
Myclass.m
+ (instancetype)shareInformation
{
static Myclass *manager;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
manager = [[Myclass alloc] init];
});
return manager;
}
MyNextClass.m
[[Myclass shareInformation] methodofMyclass:^(NSDictionary *results, NSError *error) {
//my code
}];
i have a class Myclass in which i am using a singleton to init manager = [[Myclass alloc] init]; and i am calling this in other class MyNextClass but i don't want to do this in this way i mean i don't want to use singleton pattern i need some this alternative for what i do here
I'm guessing you want to avoid using the singleton as it's considered an anti-pattern.
A solution would be to use a dependency injection container to wire up your application and configure it to resolve your object as a single instance.
I'm not familiar with ios development but Typhoon looks like popular choice.
You can use a singleton or you can use a normal instance, it's up to you. One of the major benefits of a singleton is so that you can get a reference to it anywhere without difficulty.
You could always create a class, and pass a reference of it anywhere you want to use it. For example in your view controller you create it, make sure you create a property of it in your following view controllers and then pass that same reference to the new view controller.
It's best to use a singleton if that's what you're trying to accomplish and you only need one instance though.
Another option, for "global" data, is to make use of the AppDelegate. You can place simple properties in the AppDelegate itself, or define a property (or explicit "getter" method) which returns a pointer to some more complex "global" object.
Note that using the AppDelegate this way is considered "bad form" by many, but there's really not that much bad about it, other than accessing the AppDelegate itself is a bit awkward. (And it upsets the sensibilities of those who are sure they know what "separation of concerns" really means.)

Should I avoid a Singleton in this case?

I've been thinking about using a singleton on my data class in my current app. I've also been thinking of reasons not to use the pattern and currently I am stuck in the middle.
The reason I am for the singleton in this case is due to accessibility to methods and properties easily that I need to use more than once throughout the app. I could use the appDelegate for this but that muddles up the area of concern as these methods / variables have nothing to do with the app state - more to do with user input. The data will be persisted with eventually with NSUserDefaults - which is a singleton already.
The reason I am against it is because its another singleton to an app that already bass one (The appDelegate)
My question:
Would using another Singleton to access the data model be the correct way / acceptable way of doing it - or should I look at another approach?
I personally think there would be nothing wrong with a singleton as a data model - using the app delegate to instantiate it when the app starts and then access its various methods / properties when I need them throughout the app. This would be the only other singleton in the app (Maybe another one for user management - e.g.; logging in / out / profile / credentials, etc? )
Any thoughts?
Thanks all!
There is no problem having multiple singleton classes within ios, in fact in many of my projects most of the classes are singletons. Normally I have the data access logic and control within a singleton and then actual object classes as instances.
As you have already identified you really do not want to be putting something into AppDelegate that does not apply to the whole app.
From my point of view do not instanciate the class from AppDelegate, simply have the class instanciate itself on first access.
Whenever I am explaining singleton Objective-C to people I always direct them to this site, it may be worth a view for you:
http://www.galloway.me.uk/tutorials/singleton-classes/
It explains only what you need in a really easy to understand way. The bit that does the 'self-instanciating' is this bit:
+ (id)sharedManager {
static MyManager *sharedMyManager = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
sharedMyManager = [[self alloc] init];
});
return sharedMyManager;
}
You could use singleton in these case. Don't use delegate to hold values for your app. You may use same singleton for user management also.
Note : Don't use globals unless you need to do so. Singletons and top-level data should be used only when the data they contain truly belongs at the top level.

How to create a global object class in Objective-c available to all other classes

I would like to create some type of object or class that stores a whole bunch of variables I get from a server at one point in my application. I would then like to make this object or class available to the whole project so that I can make use or even update the variables of this object or class.
I have no idea where to start with this as I am not even sure if it's possible.
Currently the problem I am facing is that I have all of these objects passing data around different classes and I'm pretty much nesting these objects and its become very inefficient to keep track of this code. However if I had some type of class that I could just access from anywhere with all of the values up to date this would make my life a lot easier.
You need to create an object that you access through this:
+ (MySingleton *)sharedMySingleton
{
static dispatch_once_t shared_initialized;
static MySingleton *shared_instance = nil;
dispatch_once(&shared_initialized, ^ {
shared_instance = [[MySingleton alloc] init];
});
return shared_instance;
}
As the comments said it is a singleton pattern. The first time you access your object it is created, then each subsequent time you get the same object when you call [MySingleton sharedMySingleton];
A singleton is the way to go.
+(SharedClass *) sharedHelper {
static sharedClass *sharedInstance = nil;
static dispatch_once_t pred;
dispatch_once(&pred, ^{
sharedInstance = [sharedClass alloc];
sharedInstance = [sharedInstance init];
});
return sharedInstance;
}
I would suggest creating a data container singleton. A singleton is an object that gets created once and only once during the life of the project. It has a class method that lets you request the object.
Search on "Cocoa singleton design pattern" to find more about it.
You might have a class MyDataObject, and it might have a class method sharedDataObject. The contents of the .m file might look like this:
#implementation MyDataObject
static _sharedDataObject;
+(MyDataObject) sharedDataObject
{
if (!_sharedDataObject)
_sharedDataObject = [[MyDataObject alloc] init];
return _sharedDataObject;
}
#end
Then you just add properties to the header of the data object as needed. Anywhere you need it, #import the header for the data object in your other classes, and then use code like this:
//To store a value to a property in the shared data object:
[MyDataObject sharedDataObject].someProperty = someValue;
//To fetch a value:
someValue = [MyDataObject sharedDataObject].someProperty;
If you need the contents of your shared data object to persist, you can make the shared data object conform to NSCoding, and then save its contents to a file when your app shifts to the background, and load its contents from a file on launch.
Note that Cocoa and Cocoa touch use a lot of singleton objects. NSUserDefaults is a singleton, and so is NSFileManager. The tip-off for a singleton is the use of a class method to return a single object. Often in Apple's frameworks the class method's name will start with "shared" or "default"
Singleton is a good pattern for create one singleton object in your program, for the objects that does not interact with other singletons.
If you have many singleton objects with complexity interaction, you should have more control of creation of your objects.
You can use your AppDelegate, and create Singletons in ApplicationDidFinishLaunching as fields of your AppDelegate.
Or you can create one Singleton object, that will contain other objects and will create other objects with necessary logic.

Static Class vs Singleton [duplicate]

This question already has answers here:
Singleton Instance vs Class Methods
(2 answers)
Closed 9 years ago.
So, pretty simple question. Ignoring the implications of over-use of the singleton pattern. I'm trying to find a reliable singleton patter in Objective-C. I have come across this:
#implementation SomeSingleTonClass
static SomeSingleTonClass* singleInstance;
+ (SomeSingleTonClass*)getInstance
{
static dispatch_once_t dispatchOnceToken;
dispatch_once(&dispatchOnceToken, ^{
singleInstance = [[SomeSingleTonClass alloc] init];
});
return singleInstance;
}
- (void)someMethodOnTheInstance
{
NSLog(#"DO SOMET WORK")
}
#end
This I am fairly happy with but it leads to a lot of this:
[[SomeSingleTonClass getInstance] someMethodOnTheInstance];
My question is, why is this better than a purely static class.
#implementation SomeStaticClass
static NSString* someStaticStateVariable;
- (id)init
{
//Don't allow init to initialize any memory state
//Perhaps throw an exception to let some other programmer know
//not to do this
return nil;
}
+ (void)someStaticMethod
{
NSLog(#"Do Some Work");
}
All you really gain, is mildly cleaner looking method calls. Basically you swap out this:
[[SomeSingleTonClass getInstance] someMethodOnTheInstance];
For this
[SomeStaticClass someStaticMethod];
This is a minor simplification for sure, and you can always store the instance within your class. This is more intellectual curiosity, what Objective-C god am I pissing off by using static classes instead of singletons? I'm sure I can't be the first person to think this, but I promise, I did a duplicate search first. The few answers I found, I felt like were based on older versions of cocoa, because even the discussed singleton patterns seemed to suffer from threading issues.
Static class : Used when you want to group together utility methods that are state independent.
Singleton : Used when you have multiple methods that share a state.
I've found it convenient to do a mix of both. I use a standard singleton pattern similar to your first that results in:
[[MyClass defaultInstance] doSomething];
But I also want to be able to create other instances of the same class:
MyClass *secondInstance = [[MyClass alloc] init];
[secondInstance doSomething];
When I want more concise access to call methods on the singleton instance, I define class methods as follows:
// class method to call a method on the singleton instance
+ (void)doSomething
{
[[MyClass defaultInstance] doSomething];
}
So with that, I can use:
[MyClass doSomething];
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.
The first example seems to be needlessly creating a singleton-like instance of a class. I say needlessly because from your other comments it appears that the class doesn't declare any properties or instance variables. Given that the fundamental purpose of an object is to provide storage for state, an object with no instance variables is rarely a useful thing.
Your second example shows a class that would never be instantiated. Again, the fundamental purpose of a class in Objective-C is to act as a factory for instances, so a class that's never instantiated isn't really useful or necessary.
Instead, you can just provide a set of C functions. C functions don't need to be associated with a class at all. So consider doing something like this:
static NSString* someStaticStateVariable;
void someFunction(void)
{
NSLog(#"Do Some Work");
}
The functions can be in separate .h/.m pair, or can be incorporated in the .h/.m for an existing class if it makes sense to do so (generally, if the functions are closely associated with the concerns of that class).

Resources