2013-08-07 7 views
6

どちらの初期化子を指定し、どの初期化子をどちらの初期化子にするかを理解しようとしています。私はそのトピックでリンゴのドキュメントを読むが、私はまだよく分からない。指定された初期化子はクラスに必要なすべての値を持っていなければなりませんか?例
これについて私はobjective-cの初期化子と便利初期化子を指定し、それらを適切に作成して結び付ける方法

-(id)initWithCardCount:(NSUInteger)cardCount usingDeck:(Deck *)deck 
{ 
    self = [super init]; 
    if (self) { 
     for(int i = 0; i<=cardCount;i++){ 
      Card *card = [deck drawRandomCard]; 
      if (!card) { 
       self = nil; 
       break; 
      }else{ 
       self.cards[i] = card; 
      } 
     } 
    } 

    return self; 
} 

を作成した最初の指定イニシャライザは今、このクラスにcardMatchModeプロパティをADDEたし、初期化子でそれを設定したいと思います。クラスの下位互換性を保ち、初期化子を理解するために、私は今持っているものを保持していて、別の初期化子を作成しています。

-(id)initwithCardCount:(NSUInteger)cardCount usingDeck:(Deck *)deck cardMatchMode:(NSUInteger)matchMode 
{ 

    _cardMatchMode = matchMode; 
    return [self initWithCardCount:cardCount usingDeck:deck];; 
} 

リンゴのドキュメントに基づいて利便初期化子は、指定イニシャライザの値を返すために持っていますが、問題は、私はコンビニエンス初期化子で、このクラスに余分なプロパティを設定することができますか? self.cardMatchMode = matchMode;と言うことはできますか、またはselfはまだ完全に初期化されていませんか?
それは作業を行いますが、私はただ、これは適切なコードであれば理解したかったと私はコンビニエンスINITにcardMatchModeプロパティにアクセスすることができますか私は指定イニシャライザと他の1つのコンビニエンスのinitとして -(id)initwithCardCount:(NSUInteger)cardCount usingDeck:(Deck *)deck cardMatchMode:(NSUInteger)matchMode

をしなければならないでしょうし、コードを修正しますか?ありがとう!私はself = [self initWithCardCount:(NSUInteger)cardCount usingDeck:(Deck*)deck; を実行しようとしましたときに

/////更新

私は

-(id)initwithCardCount:(NSUInteger)cardCount usingDeck:(Deck *)deck cardMatchMode:(NSUInteger)matchMode 

でエラーを取得したエラーは、初期化、家族外の自己を割り当てることができないと述べました。私はそれが何か問題であると考えました。 initメソッドは小文字のwを持ち、大文字でなければなりませんでした。これは私の利便性イニシャライザのコードです。

-(id)initWithCardCount:(NSUInteger)cardCount usingDeck:(Deck *)deck cardMatchMode:(NSUInteger)matchMode 
{ 
    self = [self initWithCardCount:cardCount usingDeck:deck]; 
    if (self){ 
     _cardMatchMode = matchMode; 
    } 
    return self; 
} 

これは意味があります。私はスーパーを呼び出す指定されたinitを呼び出し、次にcardMatchMode変数を設定します。

私の知る限り、余分なパラメータを持つ便利な初期化子を持つ多くのオブジェクトがあり、それはちょうどinitを呼び出すだけです。あなたはNSStringを見て、それは異なるパラメータで異なる初期化子を持っています。おそらく、指定された初期化子であるinitを呼び出すでしょう。これは正しいです?

+0

あなたは、コンストラクタのオーバーロードについて聞いたことがありますか?指定されたイニシャライザは、実際のコンストラクタとしてのJavaのようなもので、ほとんどのパラメータが必要です。そして、 'コンビネーションイニシャライザ'は '指定されたイニシャライザ'を呼び出して 'super init'を呼び出します。 –

答えて

6

initalizer指定された通常のinitです...ほとんどのパラメータを持ち、ほとんどの初期化作業を行うメソッドです。

したがって、これは- (id)initwithCardCount:(NSUInteger)cardCount usingDeck:(Deck *)deck cardMatchMode:(NSUInteger)matchModeになります。その他の初期化子は引数が少なくなり、指定された初期化子に欠落しているパラメータをデフォルト値またはその他の推定値で埋めます。

したがって、それぞれの便利な初期化子は、スーパークラスの初期化子ではなく、指定された初期化子を呼び出します。

利便-指定イニシャライザのペアは、あなたの場合には次のようになります。

/** 
Convenience initializers 
*/ 
- (id)init 
{ 
    self = [self initwithCardCount:kDefaultCardCount usingDeck:[Deck defaultDeck] cardMatchMode:kCardMatchModeDefault]; 
    return self; 
} 

- (id)initWithCardCount:(NSUInteger)cardCount usingDeck:(Deck *)deck 
{ 
    self = [self initwithCardCount:cardCount usingDeck:deck cardMatchMode:kCardMatchModeDefault]; 
    if (self) { 

    } 

    return self; 
} 

/** 
Designated initializer 
*/ 
- (id)initwithCardCount:(NSUInteger)cardCount usingDeck:(Deck *)deck cardMatchMode:(NSUInteger)matchMode 
{ 
    self = [super init]; 
    if (self) { 
     for (int i = 0; i <= cardCount; i++) { 
      Card *card = [deck drawRandomCard]; 
      if (!card) { 
       self = nil; 
       break; 
      } 
      else { 
       self.cards[i] = card; 
      } 
     } 
     // Set card match mode here: 
     _cardMatchMode = matchMode; 
    } 

    return self; 
} 
+1

返事をありがとう。私の更新された答えをチェックしてください。この場合、私は実際にinitを呼び出す人を望んでいません。なぜなら、このクラスを初期化するときにパラメータを渡すようにしたいからです。デフォルトのパラメータはありません。長期的には、指定されたと便利なinitが指定されている限り、どれくらい多くのパラメータがスーパーと呼ばれ、便宜的に呼び出されるかは関係ありません。 – Yan

15

指定された初期化子は、クラスのスーパークラスの指定された初期化子を呼び出すものであるため、オブジェクトsuperのメソッドを呼び出す唯一の初期化子です。クラスの他の初期化子はそれを行うべきではありません。これらの二次イニシャライザはselfを使用して指定されたイニシャライザを起動する必要があります。通常、指定された初期化子には、クラスの有用なオブジェクトを作成するために必要なすべてのパラメータがあります。

要は、superでイニシャライザを呼び出す唯一のイニシャライザであり、クラス内の他のすべてのイニシャライザは、指定されたイニシャライザ(selfを使用)を呼び出します。アップルのドキュメントによると

+0

返事をありがとう。私は今、より意味をなさないものを更新しました。指定されたイニシャライザだけがsuperを呼び出し、セカンダリが指定されたinitを呼び出す限り、私は理解できるように動作します。クラスのすべてのプロパティは、最初に指定された呼び出しを呼び出してから、残りをセカンダリで設定することによって初期化されます。 – Yan

関連する問題