2010-07-28 7 views
1

내 앱이 데이터를 저장하지 않거나 데이터를로드하지 않습니다. 단지 충돌이 발생합니다. 고득점 관리자 클래스에서 내가 뭘 잘못하고 있는지 궁금합니다. 내 클래스의 .H와하는 .m 파일을 게시 할거야Objective-C NSUserDefaults : HighScoreManager, 왜 작동하지 않습니까?

는 :

.H

#import <Foundation/Foundation.h> 

@interface Score : NSObject 
{ 
    NSString *name; 
    NSNumber *score; 
} 

@property (assign, nonatomic) NSString *name; 
@property (assign, nonatomic) NSNumber *score; 

+ (Score *) score: (NSNumber *)score_ name: (NSString *)name_; 
- (id) initWithScore: (NSNumber *)score_ name: (NSString *)name_; 

@end 

@interface HighScoreManager : NSObject 
{ 
    NSArray *an_; 
    NSArray *as_; 
    BOOL loaded; 
} 

- (void) load; 
- (BOOL) noScores; 
- (NSArray *) sortedScores; 
- (void) add: (NSString *)name score: (NSNumber *)score; 

@end 

하는 .m

#import "HighScoreManager.h" 

@implementation Score 
@synthesize name, score; 

+ (Score *) score: (NSNumber *)score_ name: (NSString *)name_ 
{ 
    return [[[Score alloc] initWithScore: score_ name: name_] autorelease]; 
} 

- (id) initWithScore: (NSNumber *)score_ name: (NSString *)name_ 
{ 
    if((self = [super init])) 
    { 
     score = score_; 
     name = name_; 
    } 

    return self; 
} 

@end 

@implementation HighScoreManager 

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

    return self; 
} 

- (void) load 
{ 
    if(!loaded) { 
     NSUserDefaults *NSUD = [NSUserDefaults standardUserDefaults]; 
     [NSUD synchronize]; 
     an_ = [NSUD arrayForKey: @"game.score.names"]; 
     as_ = [NSUD arrayForKey: @"game.score.scores"]; 
     [NSUD release]; 

     loaded = YES; 
    } 
} 

- (BOOL) noScores 
{ 
    [self load]; 
    return [an_ count] < 1; 
} 

- (NSArray *) sortedScores 
{ 
    [self load]; 
    NSMutableArray *scoresObj = [NSMutableArray array]; 

    for(NSUInteger i = 0; i < [an_ count]; i++) 
    { 
     [scoresObj addObject: [Score score: [as_ objectAtIndex: i] name: [an_ objectAtIndex: i]]]; 
    } 

    NSSortDescriptor *sortDescriptor = [[[NSSortDescriptor alloc] initWithKey:@"score" ascending: NO] autorelease]; 
    NSArray *sortDescriptors = [NSArray arrayWithObject:sortDescriptor]; 

    return [scoresObj sortedArrayUsingDescriptors: sortDescriptors]; 
} 

- (void) add: (NSString *)name score: (NSNumber *)score 
{ 
    NSUserDefaults *NSUD2 = [NSUserDefaults standardUserDefaults]; 
    [NSUD2 setObject: [[NSUD2 arrayForKey: @"game.score.names"] arrayByAddingObject: name] forKey: @"game.score.names"]; 
    [NSUD2 setObject: [[NSUD2 arrayForKey: @"game.score.scores"] arrayByAddingObject: score] forKey: @"game.score.scores"]; 
    [NSUD2 synchronize]; 
} 

- (void) dealloc 
{ 
    [an_ release]; 
    [as_ release]; 
    [super dealloc]; 
} 

@end 

나는 클래스를 사용하려고 어떻게

HighScoreManager *HSM1 = [HighScoreManager new]; 
    [HSM1 add: @"Johannes" score: [NSNumber numberWithInt: 1298]]; 
    [HSM1 add: @"Johannes" score: [NSNumber numberWithInt: 8723]]; 
    [HSM1 add: @"Johannes" score: [NSNumber numberWithInt: 3283]]; 
    [HSM1 add: @"Johannes" score: [NSNumber numberWithInt: 1763]]; 
    [HSM1 add: @"Johannes" score: [NSNumber numberWithInt: 9931]]; 

    HighScoreManager *HSM = [HighScoreManager new]; 

    // Check if there even are any high scores. 
    if([HSM noScores]) 
    { 
     CCLabel *noScoresYet = [CCLabel labelWithString: @"There are no scores yet." fontName: @"Helvetica" fontSize: 36]; 
     noScoresYet.position = ccp(win.width/2, win.height/2); 
     [noScoresYet setColor: ccc3(0, 0, 0)]; 
     [self addChild: noScoresYet]; 
    } else 
    { 
     // Oh look, there were some high scores! 

    } 

    [HSM release]; 

점수를 "저장"해도 n 점수 페이지에서 벗어나 돌아가서 앱이 충돌하는 곳입니다. 나는 내가 잘못 또는 왜


를 저장하지 않는 것을 정말 모르겠어요은 "_class_getMethodNoSuper_nolock"때로는 objC_send 또는

+0

내 좋은 방법은 지금 (내 대답을 참조하십시오) –

답변

1
  • NSUD을 해제하지 마십시오. 당신은 그것을 만들지 않았고 당신은 그것을 소유하지 않았기 때문에 그것을 소유하지 않았습니다. 이로 인해 충돌이 발생할 수 있습니다.

  • 인스턴스 변수도 유지해야합니다.

  • [NSUD2 arrayForKey: @"game.score.names"]은 처음에 nil을 반환하므로 [[NSUD2 arrayForKey: @"game.score.names"] arrayByAddingObject: name]도 0이됩니다. 사전 값을 항상 nil로 설정합니다.

  • (그리고 "an_"과 같은 변수 이름을 피하기는. 그것은 코드를 읽기 어렵게한다.)

0

과 같이 정확히 위치를 설명 충돌 때이를 얻을 수 충돌이 일어나고 있고 아마도 더 많은 도움이 될 수 있습니다. 내가 발견 적어도 하나의 문제 :

return [[[self alloc] initWithScore: score_ name: name_] autorelease]; 

은이어야한다

return [[[Score alloc] initWithScore: score_ name: name_] autorelease]; 
+0

I 악보 클래스에 할당 특성에 그것을 업데이트하고 질문에 조금 더 추가했습니다. –

0

코드 만 테스트하지 않았나요 내가 처음으로 느낀 점은 클래스 대신에 자기를 ALLOC하려고 정적 팩토리 메소드입니다 나는 당신이 필요로하는 확신

점수 :

+ (Score *) score: (NSNumber *)score_ name: (NSString *)name_ 
{ 
    return [[[Score alloc] initWithScore: score_ name: name_] autorelease]; 
} 

한 가지 더. Score 클래스의 속성은 할당으로 선언됩니다. 즉 스코어와 이름을 유지하지 않으면 스코프를 벗어나면 앱이 충돌합니다.

+0

'[self alloc]'은 클래스 메서드에서 관용적입니다. '[Score alloc]'은 비정상적이며 저에게 자바처럼 들립니다. 클래스는 메서드에서 거의 이름 자체로 언급하지 않아야합니다. 당신은 아무것도 얻지 않고 유산을 상실합니다. – Chuck

+0

나는 솔직히 그 문제에 대해 그 언어 나 다른 언어처럼 쓰여진 적이 없다. 당신의 요지를 볼 수는 있지만 할당은 인스턴스 메소드가 아닙니다. 어떻게 될 수 있습니까? 인스턴스가 아직 생성되지 않았습니다.나는 항상 객체를 만드는 obj-c 방법이 이상하다는 것을 알고 있습니다. –

관련 문제