0

私は現在、Apple の「Objective C によるプログラミング」マニュアルを読んでおり、これら 2 つの init メソッドが示されています。それらの違いは何ですか?また、それぞれをいつ使用するのが適切ですか?

  - (id)initWithFirstName:(NSString *)aFirstName lastName:(NSString *)aLastName dateOfBirth: (NSDate *)aDateOfBirth {

    self = [super init];

    if (self) {
        _firstName = aFirstName;
        _lastName = aLastName;
        _dateOfBirth = aDateOfBirth;
    }

    return self;

}

- (id)initWithFirstName:(NSString *)aFirstName lastName:(NSString *)aLastName {
    return [self initWithFirstName:aFirstName lastName:aLastName dateOfBirth:nil];
}

マニュアルはここにありますhttp://developer.apple.com/library/ios/#documentation/cocoa/conceptual/ProgrammingWithObjectiveC/EncapsulatingData/EncapsulatingData.html#//apple_ref/doc/uid/TP40011210-CH5-SW15

4

4 に答える 4

3

2 つ目は循環的であり、無限再帰につながります。

編集:

更新された質問では、3 番目のパラメーターを指定する必要がなくなったため、イニシャライザーの 2 番目のバージョンは便利です。

于 2013-01-09T00:32:39.910 に答える
0

これはマニュアルに書かれていることです:

- (id)initWithFirstName:(NSString *)aFirstName lastName:(NSString *)aLastName {
    return [self initWithFirstName:aFirstName lastName:aLastName dateOfBirth:nil];
}

したがって、呼び出されたメソッドは別のメソッドであり、再帰的ではないため、無限ループは発生しません。

編集

2番目の方法は、dateOfBirthでオブジェクトを初期化したくない場合に使用します。実際、initWithFirstName:lastName:を使用する場合、このプロパティはnilになります。

于 2013-01-09T01:00:08.977 に答える
0

最初のものは通常のカスタム初期化で、パラメーターを正しく設定し、クラスを初期化します。

2 番目のものは自分自身を呼び出すため、無限再帰で何度も何度も自分自身を呼び出し、最終的にはスタック オーバーフローにつながります。アプリは本質的にフリーズしてクラッシュします。

アップルのドキュメントはそれを示唆していません....あなたはそれを読み違えたかもしれません


アップルのドキュメントはまだそれを示唆していませんが、近いです:

- (id)initWithFirstName:(NSString *)aFirstName lastName:(NSString *)aLastName {
return [self initWithFirstName:aFirstName lastName:aLastName dateOfBirth:nil]; // Not the same method, passes dateOfBirth parameter.
}

呼び出されるメソッドは次のようになります。

- (id)initWithFirstName:(NSString *)aFirstName lastName:(NSString *)aLastName dateOfBirth: (NSDate *)dateOfBirth {

   if (self = [super init]) {

         _firstName = aFirstName;
         _lastName = aLastName
         _dateOfBirth = dateOfBirth;
   }

        return self;

}

同様の別のメソッドを呼び出しますが、dateOfBirthパラメーターを渡しますが、同じメソッドではありません。


OK、違いは簡単です。いずれかのメソッドを呼び出すクラスがクラス内からパラメーターを渡したくないdateOfBirth場合、およびこの Person インスタンスdateOfBirthに指定したい . nilwilly nillyと書く。したがって、これは便利なメソッドです。a を渡さずdateOfBirth、姓と名だけを渡し、単純nilに for で他のメソッドを呼び出しますdateOfBirth。これは、コードの作成者が書くときに怖く感じないようにするための方法にすぎませんnil

したがって、両方の方法ですべてが初期化されます。

于 2013-01-09T00:37:52.600 に答える
0

@ThomasW が指摘しているように、2 番目のケースは間違っています。最初のケースでは、派生元の基本クラスに、インスタンス化するオブジェクト共有を初期化[super init]させるために呼び出します。

これは、何をすべきかを知っている基本クラスがメッセージを受信する必要があることsuperを示すため、機能します。initあなたの姓名を覚える方法がわからないことに注意してください。

ただし、2 番目のケースでは、initメッセージは に送信されself、それinitが呼び出し元です。これは、initクラッシュするまで自分自身を呼び出し続けることを意味します。

aFirstName魔法のような方法で割り当てられていると仮定しているように見えますaLastNameが、オブジェクトにこれを行う方法を教え、このinitメソッドで正確に実装する必要があります。

于 2013-01-09T00:42:30.790 に答える