objective-c中的动态链接/动态类型

时间:2012-09-03 08:07:58

标签: objective-c

我在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]

3 个答案:

答案 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本身,并没有超级对象,是吗?