1

以下のようなカスタムinitメソッドを持つ「Defense」という名前のクラスがあります。

// initialize the defense unit and add the sprite in the given layer
- (id) initWithType:(DefenseType)tType andInLayer:(CCLayer *)layer {

    NSString       *fileName;
    fileName     = [NSString stringWithUTF8String:defenseStructuresFile[tType]];

    if ( (self = [super initWithFile:fileName]) ) {

        type              =   tType;
        maxHealth         =   defenseStructuresHealth[tType];
        health            =   maxHealth;
        mapRef            =   (SkirmishMap *)layer;        
    }
    return self;
}

現在、クラスNSCodingを互換性のあるものにしています。これには、次の2つのメソッドが必要です。

- (id) initWithCoder:(NSCoder *)decoder
- (void) encodeWithCoder:(NSCoder *)encoder

通常、「防御」のインスタンスを割り当てるときは、次のようにコーディングします。

Defense                 *twr;
twr                 =   [[Defense alloc] initWithType:type andInLayer:mapRef];

保存したDefenseオブジェクトのインスタンスを復元したい場合は、次のようにコーディングします。

twr                 =   [[decoder decodeObjectForKey:kDefense] retain];

initializeしかし、上記のコードでは、オブジェクトに非常に必要な「type」パラメーターと「mapref」パラメーターを渡すことができません。

Defenseクラスはから派生し、に準拠しCCSpriteCCSpriteいないため、私のメソッドNSCodingから呼び出すのは問題ありません。ただし、initWithFileに渡すファイル名を決定するためのパラメーターが必要です。(self = [super initWithFile:fileName])initWithCodertypeccsprite's

それで、私はこの状況で何をしますか?クラスのデザインを変更する必要がありますか?はいの場合、どのように?

良いアイデア/提案は大歓迎です...:)

4

1 に答える 1

2

あなたはこのようなことをすることができます:

- (id)initWithCoder:(NSCoder *)decoder
{
    DefenseType earlyType;
    NSString *filename;

    earlyType = [decoder decodeIntegerForKey:@"defense"];

    if (earlyType == somethingIllegal) {
        [self release];
        return nil;
    }

    // Now do something with earlyType do determine filename

    self = [super initWithFilename:filename];
    if (!self) return nil;

    type = earlyType;
    // Decode the rest.

    return self;
}

メソッドが入力されると(init'sでも)、self常に設定されます。そして、それは単なる変数です(より正確には、引数)。[self release]; return nil;これが、を呼び出す前でも機能する理由superです。あなたが電話するとき、self = [super initWithFoo:];あなたは上書きしていますself。これが行われるのは、スーパークラスが[self release]; return nil;具象サブクラスを実行または割り当てて、代わりにそれを返す可能性があるためです(クラスクラスターを使用する場合)。したがって、superの初期化子を呼び出す前に、インスタンス変数を上書きすることは安全ではありませんが、通常のスタック変数(またはグローバル変数)を使用することは問題ありません。

于 2011-10-28T06:27:35.947 に答える