2

I am learning to create a singleton class in Objective-C and came across this post which uses GCD to ensure singleton pattern is enforced. I am getting confused about the instance init method in this class and why it is there.

Looks like it will be invoked when someone tries to initialize MyManager instance but why is the author trying to initialize parent class's instance ([super init]) here?

#import "MyManager.h"

@implementation MyManager

@synthesize someProperty;

#pragma mark Singleton Methods

+ (id)sharedManager {
    static MyManager *sharedMyManager = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        sharedMyManager = [[self alloc] init];
    });
    return sharedMyManager;
}

- (id)init {
    //what is purpose of initialising parent class (NSObject's) instance
    if (self = [super init]) {
        someProperty = [[NSString alloc] initWithString:@"Default Property Value"];
    }
    return self;
}

- (void)dealloc {
  // Should never be called, but just here for clarity really.
}

@end
Rob
  • 415,655
  • 72
  • 787
  • 1,044
java_doctor_101
  • 3,287
  • 4
  • 46
  • 78
  • 1
    http://stackoverflow.com/questions/2956943/why-should-i-call-self-super-init and http://stackoverflow.com/questions/18693023/objective-c-questions-about-self-super-init Your question is not related really to Singleton, since we almost always call a [super init] in custom initialization method. – Larme Sep 05 '16 at 16:11

1 Answers1

1

One subtle point of confusion with ObjC is that the language does not have static methods. It has class methods.

That is, the methods prefixed by + are attached to the Class object and are inherited and can be overridden just like instance methods.

Thus, when writing a singleton, the initialization of the singleton instance works just like every other instance initialization in that the superclass is given an opportunity to initialize, too.

Since most singletons inherit from NSObject, it is a no-op.

But, sometimes, you end up with:

NSObject
   AbstractSingletonThatIsNeverDirectlyInstantiated
      ConcreteSingletonForLocalOnlyMode
      ConcreteSingletonForOnlineMode

(Totally made up example, but I've seen similar.)

bbum
  • 162,346
  • 23
  • 271
  • 359
  • While all objects subclass from `NSObject`, you should not subsequently subclass singleton classes. You have no assurances whether the singleton refers to the base singleton class or to one subclass or the other. (Besides, I think the OPs question is far simpler, just asking why `init` calls `[super init]`.) – Rob Sep 05 '16 at 17:11
  • @Rob In this case, AbstractSingleton would never be instantiated, but the two Concrete subclasses would. And, yes, there are patterns where having one of each floating about is perfectly valid. Edited for clarity. It is akin to a class cluster, but a singleton cluster. – bbum Sep 05 '16 at 19:30
  • Sure, but even if the base singleton is abstract, you still have problem with two singleton subclasses, as they share the `sharedManager` and `onceToken`. Thus, as soon as one concrete singleton is instantiated, you can't properly instantiate a singleton of the other concrete subclass. Basically, every singleton class needs its own `sharedManager` and its own `onceToken`( or the abstract base class needs something a lot more complicated than `dispatch_once` to achieve some thread-safe singleton factory (!) pattern). – Rob Sep 05 '16 at 19:42
  • 1
    Yup; all problems that exist. In the two cases where something like this has been used, the Abstract contained shared logic and the common backing was in a `_LocalOnlineBackingStore` singleton equivalent. Both "local" and "online" shared instances can simultaneously exist while still sharing logic and the same set of data through the Abstract inheritance. I'm not saying it is a particularly *good* pattern; but it exists and works. – bbum Sep 06 '16 at 17:38