Reputation: 19
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]
Upvotes: 0
Views: 118
Reputation: 19
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?
Upvotes: 0
Reputation: 46598
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)
Upvotes: 0
Reputation: 21259
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.
Upvotes: 2