我在BNR第3版中看到了一个静态单例类的例子。 为此,他们解释了如何避免调用超类alloc的创建周期:
static MyClass *myclass = [[super alloc] init];
MyClass有自己的init方法。
NSObject -> MyClass
我的疑问是:发送了哪个init类? NSOject init或MyClass init
嵌套的alloc init等于:
myclass = [super alloc]
然后
myclass = [myclass init]
???????????
OR
myclass = [super alloc]
然后myclass = [super init]
答案 0 :(得分:2)
请勿使用super
,但请使用self
。否则,您的单例的子类化将不起作用。正确的方法是这样的:
+ (MyClass *)sharedInstance {
static MyClass *instance = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
instance = [[self alloc] init];
});
return instance;
}
dispatch_once
保证您的代码(在这种情况下为块)只被调用一次。并且self
保证子类化将正常工作。
答案 1 :(得分:0)
对于你的问题,总是在子类的实现上调用选择器,这是你的第一个猜测
书中描述的方式是实现单例的有效方法,但我不建议这样做。 Robert Vojta的解决方案很好。
我看不出有必要覆盖allocWithZone
,那么你还需要确保init
什么都不做(至少不泄漏)
答案 2 :(得分:0)
只是为了添加一些测试:
我创建了2个MyClass类:NSObject - > Myclass - > My2ndClass
所以:
@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
和
@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
然后在AppDelegate中:
Myclass *miclase = [Myclass sharedClass];
My2ndClass *mi2ndclase = [My2ndClass sharedClass];
这是控制台输出:
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
与xlc0212一样,嵌套时的正确消息是:
miclase = [super alloc];
miclase = [miclase init];
此外,如果我这样做
miclase = [super alloc]
然后
miclase = [super init]
它崩溃了。
当发送类方法(+)[超级描述]时,它会记录类名(Myclass和My2ndClass)。他们是de class本身,并没有超级对象,是吗?