-1

重複の可能性:
Objective-C では、self = [super init] が nil でないかどうかを確認する必要があるのはなぜですか?

私は Ob-C の初心者であり、「if ステートメント」でテストした結果、返される値が非 nil である理由を理解するのに苦労しています。

- (id)init
{
    self = [super init];
    if (self) {
        // Initialization code here.
    }

    return self;
}

このメソッドは、最初に親イニシャライザを呼び出します。親の初期化子を実行すると、継承されたインスタンス変数が適切に初期化されます。親の init メソッドを実行した結果を自分自身に割り当てる必要があります。初期化子にはメモリ内のオブジェクトの場所を変更する権利があるためです (つまり、その参照が変更されます)。親の初期化が成功した場合、if ステートメントでテストされているように、返される値は非 nil になります。コメントが示すように、次のブロック内に、オブジェクトの独自のカスタム初期化コードを配置できます。これには、多くの場合、クラス内のインスタンス変数の割り当てと初期化が含まれます。

Stephen Kochan からの貼り付けコードとテキスト「Programming in Objective-C, Fourth Edition」

4

1 に答える 1

2

Parent次のシナリオを考えてみましょう。次のレイアウトを持つ、と呼ぶ親クラスがあります。

@implementation Parent {
    int value;
}

ChildのサブクラスであるクラスParentがあり、次のレイアウトがあります。

@implementation Child {
    int other;
}

サブクラス内では、というivarChildに直接アクセスすることはできません。ただし、その初期化では、 に何らかの整数が割り当てられ、 の一部の機能は、設定されているこの値に依存します。ParentvalueParentvalueParent

Childが呼び出されない場合[super init]、は初期化されず、継承するvalueの機能の一部が壊れます。このメソッドは、初期化されたオブジェクト インスタンスへのポインターを返すように定義されています。の戻り値を無視すると、問題が発生する可能性があります。これは、親の init が、アロケータによって提供された場所以外の場所にオブジェクト インスタンスを再割り当てすることを決定した可能性があるためです。ParentChildinit[super init]

たとえば、NSString は空の文字列リテラルによる初期化を検出でき、ヒープ上の参照ではなく定数 NSString 参照へのポインタを返します。したがって、呼び出し[super init]てその戻り値を無視し、 sメソッドにself渡されたポインター値を使用し続けると、突然ダングリング ポインターを使用していることになります。Childinit

これは極端なケースですが、要点は、親クラスから機能を継承する場合は、 self を に割り当て、初期化に失敗して提供されたメモリを破棄することを決定した可能性があるため、それが[super init]返されるかどうかを確認する必要があるということです。nilアロケータによって。

于 2012-11-01T04:47:28.893 に答える