1

我有一个名为“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兼容,这需要以下两种方法:

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

当我通常分配一个“防御”的实例时,我的代码如下:

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

当我想恢复防御对象的保存实例时,我编码为

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

但是在上面的代码中我不能传递对象非常需要的“type”和“mapref”参数initialize......

Defense 类派生自CCSprite并且由于CCSprite不符合,因此可以从我的方法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)然后self总是设置。它只是一个变量(或者更准确地说:一个参数)。这就是为什么[self release]; return nil;在调用super. 当你打电话时,self = [super initWithFoo:];你正在覆盖self。这样做是因为您的超类可能会执行[self release]; return nil;或分配一个具体的子类并返回它(当使用类集群时)。所以在调用super的初始化器之前,覆盖实例变量是不安全的,但是使用普通的栈变量(甚至是全局变量)是可以的。

于 2011-10-28T06:27:35.947 回答