7

我有一個自定義類,我希望保存和加載。該類包含一個NSDate,一個NSString和一個NSNumber。我在.h文件中實現了NSCoding協議。這是我迄今爲止的代碼。該日期是一個NSDate。 theName是NSString。 homeAway是NSNumber。如何使用NSKeyedArchiver編碼和解碼自定義類

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

我正在使用下面的代碼來加載我的自定義對象。當我在調試器中使用打印對象時,只有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 access access」。請幫忙...

回答

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

它應該適合您。

+0

謝謝...它確實工作! – 2011-04-24 17:19:14

+0

謝謝!我應該添加到這篇文章中:別忘了調用** super **函數!如果你不這樣做,你會得到奇怪的結果。所以:'if((self = [super initWithCoder:aDecoder])){'在上面的例子中。 – Ramon 2017-01-17 10:52:48