inheritance - 如何让 NSCoding 与对象继承一起工作?

标签 inheritance state nscoding

我正在尝试使用基本的父子对象继承系统编写一个简单的角色扮演游戏,该系统被保存并加载到游戏状态中,但是当加载发生时,父级不会出现任何数据,我很难理解为什么。

为了简单起见,我做了一个简单的父子对象继承,

Player 继承自父级Character

我将所有内容放入一个数组 (listOfPlayers) 中,然后归档对象;当我加载数据时,Character 对象不再存在。

我已将以下内容记录到控制台;

METHOD: saveGameState()
2012-07-17 20:12:24.762 TestState[72342:40b] self.listOfPlayers (1)
2012-07-17 20:12:24.762 TestState[72342:40b] p.name = BOB
2012-07-17 20:12:24.763 TestState[72342:40b] p.xp = 1000

METHOD: loadGameState()
2012-07-17 20:12:27.098 TestState[72342:40b] Last Save Date = 2012-07-17 19:12:24 +0000
2012-07-17 20:12:27.099 TestState[72342:40b] self.listOfPlayers (1)
2012-07-17 20:12:27.100 TestState[72342:40b] p.name = (null)
2012-07-17 20:12:27.101 TestState[72342:40b] p.xp = 1000
2012-07-17 20:12:27.102 TestState[72342:40b] State:Loaded

保存状态似乎正在保存名称(Character 模型的一部分),但是 那么加载状态的名称似乎为 null

我不确定我做错了什么。

我的代码现在如下;

// Inside my app delegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    // Singleton
    GameStateManager *state = [GameStateManager sharedGameStateManager];
    [state setupGameState];
    return YES;
}

// Character.h
@interface Character : NSObject
<NSCoding>
{
    NSString *name;
}

@property (nonatomic, retain) NSString *name;

@end

// Character.m
@implementation Character
@synthesize name;

#pragma mark - NSCoding

-(id)initWithCoder:(NSCoder *)aDecoder
{
    self = [super init];

    if (self) 
    {
        NSLog(@"Loading character object");
        self.name   = [aDecoder decodeObjectForKey:@"name"];
    }

    return self;
}

-(void)encodeWithCoder:(NSCoder *)aCoder
{      
    // Archive the object
    NSLog(@"Archiving character object");

    [aCoder encodeObject:self.name forKey:@"name"];
}
@end


// Player.h
#import "Character.h"

@interface Player : Character
<NSCoding>
{
    NSNumber *xp; // xp points
}
@property (nonatomic, retain) NSNumber *xp;

+(NSMutableArray *) createPlayers;
@end

// Player.m
@implementation Player
@synthesize xp;

- (id)init {
    self = [super init];
    if (self) {
    }
    return self;
}

+(NSMutableArray *) createPlayers
{
    NSMutableArray *list = [NSMutableArray array];

    Player *p1 = [[Player alloc] init];
    [p1 setXp:[NSNumber  numberWithInt:1000]];
    [p1 setName:@"BOB"];
    [list addObject:p1];
    [p1 release];

    return list;
}


#pragma mark - NSCoding

-(id)initWithCoder:(NSCoder *)aDecoder
{
    self = [super init];

    if (self) 
    {
        self.xp = [aDecoder decodeObjectForKey:@"xp"];
    }

    return self;
}

-(void)encodeWithCoder:(NSCoder *)aCoder
{      
    // Archive the object
    [aCoder encodeObject:self.xp forKey:@"xp"];
}
@end

// GameStateManager.m file    
-(void)saveGameState
{
    NSLog(@"METHOD: saveGameState()");

    self.lastSaveDate   = [NSDate date];

    NSLog(@"self.listOfPlayers (%d)", [self.listOfPlayers count]);


    for (Player *p in self.listOfPlayers) {
        NSLog(@"p.name = %@", p.name);
        NSLog(@"p.xp = %d", [p.xp intValue]);
    }

    NSString *file = kGameSaveFile;    
    NSString *documentsDirectory = [MyHelpers getDocumentsDirectory];
    NSString *gameStatePath = [documentsDirectory stringByAppendingPathComponent:file];
    BOOL result;

    NSLog(@"gameStatePath = %@", gameStatePath);

    // Set up the encoder and storage for the game state data
    NSMutableData *gameData;
    NSKeyedArchiver *encoder;
    gameData = [NSMutableData data];
    encoder = [[NSKeyedArchiver alloc] initForWritingWithMutableData:gameData];

    // Archive the object
    [encoder encodeObject:self.lastSaveDate forKey:@"lastSaveDate"];
    [encoder encodeObject:self.listOfPlayers forKey:@"listOfPlayers"];

    // Finish encoding and write to disk
    [encoder finishEncoding];
    result = [gameData writeToFile:gameStatePath atomically:YES];
    [encoder release];

    if (result == YES)
    {
        NSLog(@"Result = OK");
    } else {
        NSLog(@"Result = BAD");
    }
}

-(void)loadGameState
{
    NSLog(@"METHOD: loadGameState()");

    NSString *file = kGameSaveFile;   
    NSString *documentsDirectory = [MyHelpers getDocumentsDirectory];
    NSString *gameStatePath = [documentsDirectory stringByAppendingPathComponent:file];


    NSMutableData *gameData;
    NSKeyedUnarchiver *decoder;    
    gameData = [NSData dataWithContentsOfFile:gameStatePath];

    // Check to see if the .dat file exists, and load contents
    if (gameData)
    {
        decoder = [[NSKeyedUnarchiver alloc] initForReadingWithData:gameData];

        self.lastSaveDate = [[decoder decodeObjectForKey:@"lastSaveDate"] retain];
        self.listOfPlayers = [[decoder decodeObjectForKey:@"listOfPlayers"] retain]; 

        [decoder finishDecoding];
        [decoder release];

        NSLog(@"Last Save Date = %@", self.lastSaveDate);
        NSLog(@"self.listOfPlayers (%d)", [self.listOfPlayers count]);


        for (Player *p in self.listOfPlayers) {
            NSLog(@"p.name = %@", p.name);
            NSLog(@"p.xp = %d", [p.xp intValue]);
        }

    } else {

        NSLog(@"No game data!");
        assert(-1);
        abort();

    }


    NSLog(@"State:Loaded");
}

编辑,

我认为它必须有 if ((self = [super initWithCoder:aDecoder]) )[superencodeWithCoder:aCoder];

最佳答案

使用

 if ( (self = [super initWithCoder:aDecoder]) ) and [super encodeWithCoder:aCoder];

帮助我解决了这个问题,还有这个question有也有帮助的答案。

谢谢

关于inheritance - 如何让 NSCoding 与对象继承一起工作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11529515/

相关文章:

ios - 使用自定义对象保存 NSMutableArray 时出现问题

ios - 将MessageObject从ObjC传递到Swift(虫洞)

java - 为什么这一行不能编译 List<Object> l = new ArrayList<String>()?

c++ - 如何创建采用基类和派生类的函数的专用版本和默认版本?

c++ - 具有共同祖先的模板参数推导

javascript - React Router DOM 无法读取位置状态

ios - NSKeyedArchiver 不保存自定义对象属性

javascript - 为什么 YUI.lang.extend 以这种方式实现继承?

c# - session 状态奇怪的行为

angularjs - 不同状态不显示模板内容