5

私は多くのチュートリアルに従ってきましたが、私は自己に陥っています。誰でも助けてもらえますか?

インスタンスメソッドである次のinitがあります。

- (id) initWithScore:(int) s {
    self = [super init];

    if (self) {
        score = s;

    }

    return self;
}

コードを読んで、自己をスーパーinitに設定したため、自己は現在スーパーを指しています。次に、self が有効かどうかを確認し、InitWIthScore で送信した値と等しいスコアを設定します。私はこれまでのところこれを持っています。

しかし、今はスーパーを指す自己を返すので、サブクラスを返すにはどうすればよいですか?

したがって、誰かが私のクラスを呼び出して 100 を渡したとしましょう。私のコードはクラスではなくスーパーを返しているので、どのように機能しますか? 呼び出しコードのスコアが 100 になるのはなぜですか?

もちろん、はい、動作しますが、理由はわかりません:-(

4

2 に答える 2

5

このコンストラクトは、イニシャライザ (superイニシャライザと作成中のイニシャライザの両方) を失敗させる方法で許可します -nilオブジェクトを初期化できない場合に返されます。それが、呼び出し後にをチェックする理由でもありnilます。initsuper

と の両方が、メモリ内の同じデータ構造、つまり割り当てたオブジェクトを指していますselfsuper違いは、これらの特別なポインターの言語セマンティクスにあります。

を使用するselfと、Objective-C コンパイラは現在の型でメソッドとオーバーロードの解決を開始します。

を使用するsuperと、Objective-C コンパイラはクラスの直接のスーパー タイプでメソッドとオーバーロードの解決を開始します。言い換えれば、super現在のクラスに同じメソッドが存在する場合でも、スーパークラスのメソッドを呼び出すことができるという意味です。

言い換えると、(少し簡略化して)superはメモリ位置をスーパー クラス (たとえば、サブクラス化した型、多くの場合NSObject)のインスタンスであるかのようにself扱い、メモリ位置を定義した型への通常のポインタとして扱います。

デバッガーで印刷するsuperself、同じメモリ位置を指していることがわかります。

于 2012-08-25T10:00:10.873 に答える
3

オブジェクト作成呼び出し全体は、次のようになります。

SomeClass *foo = [[SomeClass alloc] initWithScore:100];

ここで最初に行われるのは、 の呼び出し[SomeClass alloc]です。これにより、メモリ内に構造体が作成さSomeClassれ、それへのポインターが返されます。次はself、前のステップからのポインタである初期化のものです。したがってself、 は class のオブジェクトを指しますSomeClass

ただし、割り当ては少し奇妙に見えます。

self = [super init];

ほとんどの場合、[super init]は変更されずself、 によって作成されたポインタを返すだけ[SomeClass alloc]です。ただし、割り当てパターンでは、2 つの追加オプションを使用できます。

  1. スーパークラスinitは を返すことで構築エラーを通知できます。nilこの場合、後続の初期化子はすべて抜け出し、nilオブジェクトを取得します。

  2. selfスーパークラスの初期化子は、たとえば、精巧なキャッシングが行われている場合などに、別のポインターを返すことを決定する場合があります。ポインターは、コードが機能するように、型のオブジェクトを指す必要がありSomeClassます (などにアクセスできますscore)。

Mike AshによるThe How and Why of Cocoa Initializersを読むことをお勧めします。はい、 driis が指摘したように、両方が同じオブジェクトを指しているselfことを認識するのは非常に良いことです。super

于 2012-08-25T09:55:58.660 に答える