如何使用NSKeyedArchiver对自定义类进行编码和解码

时间:2011-04-24 03:41:33

标签: xcode memory-management nskeyedarchiver nscoding saving-data

我有一个我希望保存和加载的自定义类。该类包含NSDate,NSString和NSNumber。我在.h文件中实现了NSCoding协议。这是我到目前为止的代码。 theDate是一个NSDate。 theName是NSString。 homeAway是NSNumber。

-(void)encodeWithCoder:(NSCoder *)aCoder {
[aCoder encodeObject:theDate forKey:@"theDate"];
[aCoder encodeObject:theName forKey:@"theName"];
[aCoder encodeObject:homeAway forKey:@"homeAway"];
}

-(id)initWithCoder:(NSCoder *)aDecoder {
if ((self = [super init])) {
    theDate = [aDecoder decodeObjectForKey:@"theDate"];
    theName = [aDecoder decodeObjectForKey:@"theName"];
    homeAway = [aDecoder decodeObjectForKey:@"homeAway"];
}
return self;
}

我使用下面的代码加载我的自定义对象。当我在调试器中使用print-object时,homeAway只显示为实际对象。 theDate和theName说0x4e4f150似乎没有指向有效的对象。

[gamesArray setArray:[NSKeyedUnarchiver unarchiveObjectWithFile:path]];  
Game *loadedGame = [gamesArray objectAtIndex:gameNumber];

我使用以下代码保存数据:

我用它来打电话给我的班级来创建一个新游戏(我试图保存的自定义类)。代码最多为NSDate * aDate = [gameDate date];是无关紧要的。

-(void)newGame {
if (homeAway != 0) {
    if (dateChanged == 1) {
        if ([nameField.text length] > 0) {
            [homeButton setImage:[UIImage imageNamed:@"HomeGray.png"] forState:UIControlStateNormal];
            [awayButton setImage:[UIImage imageNamed:@"AwayGray.png"] forState:UIControlStateNormal];
            [dateButton setImage:[UIImage imageNamed:@"DateGray.png"] forState:UIControlStateNormal];
            [nameField setBackground:[UIImage imageNamed:@"textField.png"]];
            NSDate *aDate = [gameDate date];
            NSString *aString = [[[NSString alloc] initWithString:[nameField text]] autorelease];
            UIApplication *app = [UIApplication sharedApplication];
            [[[(miShotTrackAppDelegate *)[app delegate] viewController] courtViewOne] newGame:aDate withName:aString andPlace:homeAway];
            [loadTable reloadData];
            datePicke = 0;
            homeAway = 0;
            dateChanged = 0;
            nameField.text = @"";
            [self goBack];
            [self autoSave];
        }
    }
}

}

从这个方法我调用newGame方法

-(void)newGame:(NSDate *)theDate withName:(NSString *)theName andPlace:(int)homeAway {

Game *newGame = [[Game alloc] init];
NSDate *tDate = [NSDate new];
tDate = theDate;
[newGame setTheDate:tDate];
NSString *tString = [NSString stringWithString:theName];
[newGame setTheName:tString];
NSNumber *theNumber = [NSNumber numberWithInt:homeAway];
[newGame setHomeAway:theNumber];
[gamesArray addObject:newGame];
gameNumber = [gamesArray count] - 1;
NSString *path = [self findGamesPath];
[NSKeyedArchiver archiveRootObject:gamesArray toFile:path];
[newGame release];
}

为什么我的物品不会保存?复制我的对象是否与它有关?我在评论行上看到“错误访问”的错误。请帮忙......

1 个答案:

答案 0 :(得分:6)

你没有正确实现-initWithCoder。 -decodeObjectForKey返回自动释放的对象。所以你编写这个方法的方式,你最终会得到所有游戏ivars的悬空指针。将-initWithCoder更改为:

-(id)initWithCoder:(NSCoder *)aDecoder 
{
  if ((self = [super init])) {
    [self setTheDate:[aDecoder decodeObjectForKey:@"theDate"]];
    [self setTheName:[aDecoder decodeObjectForKey:@"theName"]];
    [self setHomeAway:[aDecoder decodeObjectForKey:@"homeAway"]];
  }
  return self;
}

它应该适合你。