Create singleton using GCD's dispatch_once in Objective-C
This is a perfectly acceptable and thread-safe way to create an instance of your class. It may not technically be a "singleton" (in that there can only ever be 1 of these objects), but as long as you only use the [Foo sharedFoo]
method to access the object, this is good enough.
Usage of dispatch_once
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
Creating a singleton class with dispatch_once for class hierarchy
Unless you have a good reason, you should generally avoid subclassing singletons. It creates a very confusing situation. If you create a singleton MyClass
, can you then create a singleton FirstClass
? Since FirstClass
must always be useable anywhere MyClass
is usable (by Liskov), now there are three "singleton" MyClass
objects. Now ObjC is very loose with singletons, and that's a good thing, but this is still very strange.
OK, that said, what about your problem? First the solution, then the answer. The solution is that MyClass
probably shouldn't be a singleton, as discussed above. Get rid of getInstance
in the superclass and just define it in the subclasses.
The answer to what is happening is in your dispatch_once
. You're passing the same static once
token in all cases. dispatch_once
will run no more than one time ever for a given token. The only way around this is to pass different tokens for each class, and I don't know of a convenient way to do that without duplicating the dispatch_once code in each file. You could try to create different once
tokens for each subclass, but that's likely to be more trouble and code than just duplicating the sharedInstance
method.
BTW, don't call it getInstance
. "get" has special meaning in ObjC, and you don't mean that here, so it's confusing. This is typically called sharedInstance
, or better sharedSomething
where "something" is your class. If you really do mean that there should be a MyClass
and there should be a FirstClass
and there should be a SecondClass
, you can implement sharedInstance
in all three.
Init Method in Singleton Class (Objective-C)
See this link Create singleton using GCD's dispatch_once in Objective C for the recommend approach to creating a singleton.
Using gcd, the code becomes thread-safe. Most people now consider the case that someone calls [[Singleton alloc] init] a bug that you wouldn't write code for, so the init method should just initialise the object.
How dispatch_once works in a category in objective c?
dispatch_once()
works the same no matter what compilation unit it is in. So, yes, it will initialize lightYellowBGColor
exactly once.
Note that the method name GetCustomColorLightYellowBGColor
really should be just customColorLightYellowBGColor
and it should be a class method, not an instance method, as you don't need to instantiate a UIColor to have the method work.
Better, it shouldn't be a category on UIColor
at all. While convenient, categories lead to messy code because you are effectively interleaving your app specific code with the framework code.
A typical pattern for this sort of thing would be to have a MyAppConfiguration
class or something that contains a bunch of methods for retrieving configuration items like this. This also lays the easy foundation for allowing the user to customize the app's configuration and/or presentation by pooling all the configurable items in one place.
Objective-C singleton GCD - [self alloc] or [Class alloc]
The reason, in this case, to use [self new]
instead of [MyClass new]
, and to use static id sharedInstance
instead of static MyClass *sharedInstance
, is because you can just copy and paste the entire method without editing it. Nothing in the method is specific to the class it belongs to.
Could `dispatch_once` created singleton got released? If so, how to deal with it?
Yes.
First best practice is generally going to be to avoid the singleton in the first place.
You can also use the @synchronized(self)
pattern in place of the dispatch_once
pattern to guarantee only a single object exists at one time, but that it can be re-instantiated if it is ever deallocated for any reason.
You could also reset your dispatch_once
variable in dealloc, I think
Safe way to create singleton with init method in Objective-C
Instead of transparently redirecting calls to init
to the singleton implementation which can cause very confusing behaviour for the users of your SDK, I suggest not allowing to call init at all:
+ (instancetype)sharedInstance {
static dispatch_once_t once;
dispatch_once(&once, ^{
sharedInstance = [[self alloc] initPrivate];
});
return sharedInstance;
}
- (instancetype)init {
@throw [NSException exceptionWithName:NSInternalInconsistencyException reason:@"..." userInfo:nil];
}
- (instancetype)initPrivate {
if (self = [super init]) {
...
}
return self;
}
Related Topics
Take Screenshots in the iOS Simulator
How to Make a Uitextfield Move Up When the Keyboard Is Present - on Starting to Edit
Vertically Align Text to Top Within a Uilabel
Figure Out Size of Uilabel Based on String in Swift
Can You Build Dynamic Libraries For iOS and Load Them At Runtime
Error: 'Flutter/Flutter.H' File Not Found When Flutter Run on Ios
Get Button Click Inside Uitableviewcell
Set Padding For Uitextfield With Uitextborderstylenone
Why It Shows "Ld: Framework Not Found Bolts"
How to Show Verification Code Suggestion on Keyboard from Message
How to Check For an Active Internet Connection on iOS or Macos
Converting Nsstring to Nsdate (And Back Again)
Library? Static? Dynamic? or Framework? Project Inside Another Project
How to Change the Name of an iOS App