I have a 2 child classes that inherit from 'MyClass' and each child class should be a singleton.
I've used this pattern for getting a static instance when I don't have any other classes inheriting:
+ (MyClass *)getInstance
{
static dispatch_once_t once;
static MyClass *instance;
dispatch_once(&once, ^{
instance = [[MyClass alloc] init];
});
return instance;
}
This works just great. Now, if I add two new child classes, FirstClass and SecondClass, both of which inherit from MyClass, how do I ensure that I get back the respective ChildClass?
dispatch_once(&once, ^{
// No longer referencing 'MyClass' and instead the correct instance type
instance = [[[self class] alloc] init];
});
FirstClass *firstClass = [FirstClass getInstance]; // should be of FirstClass type
SecondClass *secondClass = [SecondClass getInstance]; // should be of SecondClass type
Doing the above means that I always get back whatever class I instantiated 1st as my second class type:
first: <FirstClass: 0x884b720>
second: <FirstClass: 0x884b720>
// Note that the address and type as identical for both.
What's the best way to create the respective child class singletons without adding getInstance
method to each of the child classes?
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With