Create Singleton Using Gcd'S Dispatch_Once in Objective-C

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



Leave a reply



Submit