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

发布于 2024-11-03 08:31:54 字数 2826 浏览 0 评论 0原文

我有一个想要保存和加载的自定义类。该类包含一个 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];
}

为什么我的对象不会保存?复制我的对象与此有关吗?我确实在注释行上收到一个错误,上面写着“exc bad access”。请帮忙...

I have a custom class that I wish to save and load. The class contains an NSDate, an NSString, and an NSNumber. I have implemented the NSCoding protocol in the .h file. Here is the code I have so far. theDate is an NSDate. theName is the NSString. homeAway is the 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;
}

I am using the code below to load my custom object. When I use print-object in the Debugger only the homeAway shows up as an actual object. theDate and theName say 0x4e4f150 does not appear to point to a valid object.

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

I save the data using the following code:

I use this to call my class to create a new Game (the custom class that I am trying to save). The code up to NSDate *aDate = [gameDate date]; is irrelevant.

-(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];
        }
    }
}

}

From that method I call the newGame method which is

-(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];
}

Why will my objects not save? Does copying my objects have something to do with it? I do get an error on the commented line that says "exc bad access". Please help...

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

み青杉依旧 2024-11-10 08:31:54

您没有正确实施 -initWithCoder 。 -decodeObjectForKey 返回自动释放的对象。因此,按照您编写该方法的方式,您最终会得到所有 Game 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;
}

它应该适合您。

You're not implementing -initWithCoder correctly. -decodeObjectForKey returns autoreleased object. So the way you wrote the method, you're ending up with dangling pointers for all of your Game ivars. Change -initWithCoder to:

-(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;
}

and it should work for you.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文