0

我在 BNR 第 3 版中看到了一个做静态单例类的例子。为此,他们解释了如何避免调用超类 alloc 的创建周期:

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

MyClass 有自己的 init 方法。

NSObject -> MyClass

我的疑问是:发送了哪个初始化类?NSOject 初始化或 MyClass 初始化

嵌套的 alloc init 等于:

myclass = [super alloc]然后 myclass = [myclass init]?????????

或者

myclass = [super alloc]接着myclass = [super init]

4

3 回答 3

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保证子类化将正常工作。

于 2012-09-03T08:21:53.140 回答
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)

于 2012-09-03T10:22:31.093 回答
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]

它崩溃了。

当发送一个类方法 (+) [super description] 时,它会记录类名(Myclass 和 My2ndClass)。它们本身就是一流的,没有超级对象,是吗?

于 2012-09-03T16:09:46.143 回答