0

I have seen in the BNR 3rd edition an example to do a static singleton class. To do that, they explain how to avoid a creation cycle calling the superclass alloc:

static MyClass *myclass = [[super alloc] init]; 

MyClass has its own init method.

NSObject -> MyClass 

My doubt is: Which init class is sent? NSOject init, or MyClass init

Nested alloc init equals:

myclass = [super alloc] and then myclass = [myclass init] ???????????

OR

myclass = [super alloc] and then myclass = [super init]

5
  • where did your find this code? it doesn't look right. is this code been placed in alloc method? Commented Sep 3, 2012 at 8:28
  • Big nerd Ranch 3rd edition. it is inside the method: + (Myclass *) sharedStore Commented Sep 3, 2012 at 9:19
  • I'll try to trace in nslog messages to myclass in the alloc init sequence Commented Sep 3, 2012 at 9:22
  • did you override alloc method? otherwise I cannot see any reason of using super Commented Sep 3, 2012 at 9:23
  • Yes, it's overriden the allocwithzone. it sends then sharedStore message again, and that is the reason of using super. Commented Sep 3, 2012 at 9:33

3 Answers 3

2

Do not use super, but do use self. Otherwise subclassing of your singleton will not work. The correct way is something like this:

+ (MyClass *)sharedInstance { static MyClass *instance = nil; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ instance = [[self alloc] init]; }); return instance; } 

dispatch_once guarantees that your code (block in this case) is called only once. And self guarantees that subclassing will work properly.

Sign up to request clarification or add additional context in comments.

Comments

0

for you question, the selector is always called on the subclass's implementation, which is your first guess

the way described in the book is a valid way to implement singleton, but i do not suggest it though. Robert Vojta's solution is good.

i cannot see how necessary to override allocWithZone, then you also need to make sure init does nothing (at least not leak)

1 Comment

Thanks, i need to clarify the subclass calling
0

Just for add some tests:

I have created 2 MyClass classes: NSObject -> Myclass -> My2ndClass

So:

@implementation Myclass +(id) sharedClass { static Myclass *miclase = nil; miclase = [[self alloc] init]; NSLog(@"%@", [super description]); return miclase; } -(id)init { self = [super init]; NSLog(@"init de Myclass"); return self; } -(NSString *)description { return @"i am Myclass"; } @end 

AND:

@implementation My2ndClass +(id) sharedClass { static My2ndClass *miclase = nil; miclase = [[super alloc] init]; //miclase = [super init]; CRASH NSLog(@"%@", [super description]); return miclase; } -(id)init { self = [super init]; NSLog(@"init de My2ndClass"); NSLog(@"%@", [super description]); return self; } -(NSString *)description { return @"i am My2ndClass"; } @end 

Then in AppDelegate:

Myclass *miclase = [Myclass sharedClass]; My2ndClass *mi2ndclase = [My2ndClass sharedClass]; 

This is the console output:

2012-09-03 17:18:55.742 Dynamic Typing[2891:207] init de Myclass 2012-09-03 17:18:55.744 Dynamic Typing[2891:207] Myclass 2012-09-03 17:18:55.746 Dynamic Typing[2891:207] init de Myclass 2012-09-03 17:18:55.747 Dynamic Typing[2891:207] init de My2ndClass 2012-09-03 17:18:55.748 Dynamic Typing[2891:207] i am Myclass 2012-09-03 17:18:55.751 Dynamic Typing[2891:207] My2ndClass 

Like xlc0212 told, the correct messages when they are nested are:

miclase = [super alloc]; miclase = [miclase init]; 

Besides, if i do

miclase = [super alloc] 

and then

miclase = [super init] 

it CRASHES.

When is sent a class method (+) [super description], it logs class name (Myclass and My2ndClass). They are de class itself and don't have super object, do they?

1 Comment

in you test, the super in class method represent the class object of the super class, which does not have +(id)init method implemented, so it crashed

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.