7

저장하고로드하려는 사용자 정의 클래스가 있습니다. 이 클래스는 NSDate, NSString 및 NSNumber를 포함합니다. .h 파일에 NSCoding 프로토콜을 구현했습니다. 지금까지 제가 가지고있는 코드는 다음과 같습니다. theDate는 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; 
} 

다음 코드를 사용하여 사용자 지정 개체를로드하고 있습니다. 디버거에서 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]; 
     } 
    } 
} 

} 내가

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

왜 내 개체를 저장하지 않습니다이다 newGame 메소드를 호출하는 방법에서

? 내 물건을 복사하는 것이 그것과 관련이 있습니까? "나쁜 액세스"라고 말한 주석 처리 된 행에 오류가 표시됩니다. 도와주세요 ...

답변

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

감사 ... 작동 했어! –

+0

고맙습니다! 나는이 포스트에 덧붙여 야한다 : ** super ** 함수를 호출하는 것을 잊지 마라! 당신이 이것을하지 않으면 이상한 결과로 끝날 것입니다. 그래서 : 위의 예제에서'if ((self = [super initWithCoder : aDecoder])) {'. – Ramon