7

どのイニシャライザを指定し、どれを便利なイニシャライザにするかを理解しようとしています。そのトピックに関するアップルのドキュメントを読みましたが、まだわかりません。指定された初期化子には、クラスに必要なすべての値が必要ですか? たとえば、
これは私が作成した最初の指定された初期化子でした

-(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で、このクラスにプロパティを追加し、初期化子で設定したいと考えています。クラスに下位互換性を持たせ、初期化子を理解するために、現在持っているものを保持し、別の初期化子を作成しています。

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

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

Apple ドキュメントに基づいて、コンビニエンス イニシャライザは指定されたイニシャライザの値を返す必要がありますが、コンビニエンス イニシャライザでこのクラスに追加のプロパティを設定できますか? 私は言うことができますself.cardMatchMode = matchMode; か、それとも自己はまだ完全に初期化されていませんか?
それは機能しますが、これが適切なコードであるかどうかを理解したかっただけで、便利な初期化で cardMatchMode プロパティにアクセスできるか、作成する必要があります -(id)initwithCardCount:(NSUInteger)cardCount usingDeck:(Deck *)deck cardMatchMode:(NSUInteger)matchMode

指定された初期化子として、もう 1 つの便利な初期化とコードのリワーク? ありがとう!

/////アップデート

でエラーが発生しました

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

私がやろうとしたときself = [self initWithCardCount:(NSUInteger)cardCount usingDeck:(Deck*)deck; 、initファミリーの外で自分自身を割り当てることはできないというエラーが表示されました。私は何が問題なのかを理解しました。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 を呼び出しています。これは正しいです?

4

2 に答える 2

17

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

つまり、指定されたイニシャライザは でイニシャライザを呼び出す唯一superのイニシャライザであり、クラス内の他のすべてのイニシャライザは指定されたイニシャライザを ( を使用してself) 呼び出します。

于 2013-08-07T20:09:36.397 に答える
7

Apple Documentation によると、指定された初期化子

通常、最も多くのパラメーターを持ち、ほとんどの初期化作業を行う 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;
}
于 2013-08-07T20:11:29.060 に答える