Objective-Cプログラミング言語(3)定義クラス--「指定された」初期化方法


転載は出典を明記してください.http://blog.csdn.net/zhangxingping
指定した初期化方法
    前節「初期化時クラス間の調整」のinitWithName:メソッドは、Bクラスの「指定された」初期化メソッドです.「指定された」初期化方法とは、継承されたすべてのインスタンス変数が初期化されることを保証する方法(通常はsuperにメッセージを送信してスーパークラスを呼び出す初期化方法)である.この方法は初期化を行うコアであり,他の初期化方法では通常この方法が呼び出される.Cocoaプログラミングには、「指定」の初期化方法が通常、新しいオブジェクトの特性を最も決定する方法である(通常、他の初期化方法と比較してパラメータが最も多いが、例外もある).    重要な点は,継承された初期化手法が派生クラスのオブジェクトを正しく初期化しなければならないことである.この点は通常、これらの継承を書き換える初期化方法によって実現される.例えば、クラスCはBの派生クラスとして、initWithName:fromfile:.では、Cクラスは、Bから継承されたinitとinitWithName:この2つの方法がCクラスのオブジェクトを正しく初期化できることを確認する必要があります.この場合、継承された2つのメソッドをCクラスに書き換えるだけでよい.
    -initWithName:(char *)string
    {
        return [self initWithName:string fromFile:NULL];
    }

    上のCクラスのinitWithName:メソッドの書き換えでは、実際にはinitWithName:fromFile:この初期化メソッドが呼び出されています.
    これにより、Cクラスの例では、initで初期化する際に、先にCクラスのinitWithNameが呼び出され、このメソッドでは図3-3のようにinitWithName:fromFile:が呼び出される.
                                                            │                            ┌───────────────────────┐     │                ┌─── │   -init               │─────┘                │    │  -initWithName:       │<────┐     class B    │    │                       │     │                │    │                       │     │                │    │                       │     │                │    └───────────────────────┘     │                │                                  │                │                                  │                 │                                  │                │    ┌───────────────────────┐     │                └───>│    -initWithName:     │     │                ┌─── │                       │     │                │    │                       │     │     class C    └──> │-initWithName:fromFile:│─────┘                     │                       │                     │                       │                     └───────────────────────┘ 
図3-3
    図3−3では、重要な詳細を無視している.メソッドinitWihtName:fromFile:Bオブジェクトデータ部分の初期化を完了するためにsuperにメッセージを送信する必要があるCクラスの「指定された」初期化メソッド.しかし、Bクラスには初期化する方法が2つありますが、どちらを呼び出すべきですか?ここでは、Bクラスのinitメソッドを呼び出すことができない2つの理由を説明します.    ・Bクラスのinitメソッドを呼び出すと、メソッド呼び出しの「デッドサイクル」が発生します.Bクラスのinitメソッドでは、initWithName:fromFile:が呼び出され、initWithName:fromFile:fromFile:Bクラスが呼び出されたinitメソッドが呼び出されます.これにより、初期化された「デッドサイクル」が形成されます.    ●これでBクラスのinitWihNameに多重化する方法はない.    原則:クラスの「指定された」初期化メソッドでは、スーパークラスの「指定された」初期化メソッドを呼び出すためにsuperにメッセージを送信する必要があります.    指定された初期化方法はsuperにメッセージを送信することによって相互に関連付けられ、他の初期化方法はselfにメッセージを送信することによってこれらの「指定された」初期化方法に関連付けられる.    【図3】クラスA,B,Cの初期化方法の関係を示す図である.図の左端にはselfへのメッセージが表示され、右端にはsuperへのメッセージが表示される. 
                                                         │                            ┌───────────────────────┐     │                     │   -init               │─────┘                     │                       │<────┐     class A         │                       │     │                     │                       │     │                     │                       │     │                     └───────────────────────┘     │                                                   │                                                   │                                                   │                     ┌───────────────────────┐     │                ┌─── │   -init               │─────┘                ├──> │  -initWithName:       │<────┐     class B    │    │                       │     │                │    │                       │     │                │    │                       │     │                │    └───────────────────────┘     │                │                                  │                │                                  │                 │                                  │                │    ┌───────────────────────┐     │                └───>│    -initWithName:     │     │                ┌─── │                       │     │                │    │                       │     │     class C    └──> │-initWithName:fromFile:│─────┘                     │                       │                     │                       │
                    └───────────────────────┘ 
図3-4
   
注意:
Bクラスのinitメソッドではselfにメッセージを送信してinitWithName:メソッドを呼び出す.したがってinitメッセージの受信者がBクラスのオブジェクトである場合、BクラスのinitWithName:メソッドが呼び出され、initメッセージの受信者がCクラスのオブジェクトである場合、CクラスのinitWithName:メソッドが呼び出される.