0

BNR 第 3 版で、静的なシングルトン クラスを実行する例を見てきました。そのために、スーパークラスの割り当てを呼び出す作成サイクルを回避する方法を説明しています。

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

MyClass には独自の init メソッドがあります。

NSObject -> MyClass

私の疑問は次のとおりです。どのinitクラスが送信されますか? NSOject 初期化、または MyClass 初期化

ネストされた alloc init は次のようになります。

myclass = [super alloc]そして myclass = [myclass init]????????????

また

myclass = [super alloc]その後myclass = [super init]

4

3 に答える 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.

于 2012-09-03T08:21:53.140 に答える
0

ご質問のとおり、セレクターは常にサブクラスの実装で呼び出されます。これが最初の推測です

本に記載されている方法は、シングルトンを実装する有効な方法ですが、私はそれをお勧めしません。Robert Vojta のソリューションは優れています。

オーバーライドするallocWithZone必要性がわからinit ない場合は、何もしないことを確認する必要があります(少なくともリークしないでください)

于 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]

クラッシュします。

クラスメソッド (+) [スーパーディスクリプション] が送信されると、クラス名 (Myclass および My2ndClass) がログに記録されます。それらはクラスそのものであり、スーパー オブジェクトを持っていませんね。

于 2012-09-03T16:09:46.143 に答える