2009-06-08 2 views
0

제가 작성한 작은 iPhone 응용 프로그램의 경우 NSMutableArray를 정렬하려고합니다.NSMutableArray를 사용자 정의 객체로 정렬하면 일부 객체를 덮어 씁니다.

두 가지 방법이 있지만 동일한 결과가 나타납니다. 배열을 정렬하면 일부 객체가 서로 겹쳐 쓰일 수 있습니다.

첫째, 여기 내 코드입니다 :

AppDelegate.h

NSMutableArray* highScores; 

어딘가에 내려 내가 differen에서 액세스 할 수 있도록 AppDelegate.h, 나는 또한 속성이 변수를 만드는 것이 수업 :

@property (retain, nonatomic) NSMutableArray* highScores; 

내 응용 프로그램이 시작되면 파일에서 높은 점수를 읽고 NSMutableArray로 가져옵니다.

AppDelegate.m는

NSMutableData* data = [NSData dataWithContentsOfFile:highScoresPath]; 
NSKeyedUnarchiver* decoder = [[NSKeyedUnarchiver alloc] initForReadingWithData:data]; 
self.highScores = [decoder decodeObjectForKey:@"highscoresArray"]; 

나는이있는 NSMutableArray에 저장되는 객체는 타입는 HighScore에서입니다.

HighScore.h

@interface HighScore : NSObject { 

    int score; 
    int roundsPlayed; 
    int wrongAnswers; 

    NSString* name; 

    NSDate* datetime; 
} 

@property int score; 
@property int roundsPlayed; 
@property int wrongAnswers; 
@property (nonatomic, copy) NSDate* datetime; 

@property (nonatomic, copy) NSString* name; 

- (id) init; 
- (void) update:(int)roundScore:(BOOL) correct; 

@end 

HighScore.m

이제
#import "HighScore.h" 

@implementation HighScore 

@synthesize score, roundsPlayed, wrongAnswers, name, datetime; 

- (id) init 
{ 
    self.name = @""; 
    self.score = 0; 
    self.roundsPlayed = 0; 
    self.wrongAnswers = 0; 

    self.datetime = [NSDate date]; 

    return self; 
} 

- (void) update:(int)roundScore:(BOOL) correct 
{ 
    self.score += roundScore; 

    if (!correct) 
     self.wrongAnswers++; 

    self.roundsPlayed++; 
    self.datetime = [NSDate date]; 
} 

- (id) initWithCoder:(NSCoder *) decoder 
{ 
    self.name = [[decoder decodeObjectForKey:@"name"] retain]; 
    self.score = [decoder decodeIntForKey:@"score"]; 
    self.roundsPlayed = [decoder decodeIntForKey:@"roundsPlayed"]; 
    self.wrongAnswers = [decoder decodeIntForKey:@"wrongAnswers"]; 
    self.datetime = [[decoder decodeObjectForKey:@"datetime"] retain]; 

    return self; 
} 

- (void) encodeWithCoder:(NSCoder *)encoder 
{ 
    [encoder encodeObject:self.name forKey:@"name"]; 
    [encoder encodeInt:self.score forKey:@"score"]; 
    [encoder encodeInt:self.roundsPlayed forKey:@"roundsPlayed"]; 
    [encoder encodeInt:self.wrongAnswers forKey:@"wrongAnswers"]; 
    [encoder encodeObject:self.datetime forKey:@"datetime"]; 
} 

- (NSComparisonResult) compareHighscore:(HighScore*) h 
{ 

    return [[NSNumber numberWithInt:self.score] compare:[NSNumber numberWithInt:h.score]]; 
} 

@end 

, 나는 다음과 같은 코드를 사용하여 내 배열을 정렬 할 때 :

NSArray *sortedArray; 
sortedArray = [highScores sortedArrayUsingSelector:@selector(compareHighscore:)]; 

을 어떻게 든 망쳐 버린다. 내 highScores 배열, 나는 같은 점수와 이름으로 최고 점수의 amound를 얻을.

내가 뭘 잘못하고 있니?

+0

실제로 이것이 sortedArrayUsingSelector를 호출하여 실제로 발생했는지 확인하십시오. 이전과 이후에 실제 highScores 배열을 보려고 했습니까? 중복 객체를 삽입 할 수있는 객체를 highScores 배열에 추가하는 코드에 어딘가 다른 것이 있습니까? 기억하십시오 - 집합이 아니므로 동일한 높은 점수 객체를 두 번 이상 삽입하면 배열에 여러 번 나타납니다 *하지만 점수는 배열에서 실제로 객체 참조이므로 항상 동일합니다. –

+0

동의합니다. sgot의 바로 앞에있는 NSArray * sortedArray; 줄에 중단 점을 놓은 다음 gdb에 배열을 출력하십시오 :'po highScores' –

답변

1

, 당신은이 일을하지 않는 :

if (self = [super initWithCoder:coder]) { 
    // Decode your stuff here 
} 

같은 일반 init 방법. [super init]으로 전화해야합니다.

또한 문자열 속성을 copy으로 정의 했으므로 속성 구문을 사용하고 있으므로 retain은 필요하지 않습니다. 합성 된 접근 자에 의해 유지됩니다.

그렇지 않으면 코드가 정상적으로 보입니다. 모든 init 메소드는 항상 superinit... 메소드를 호출해야한다는 것을 기억하십시오.

+0

이것은 명백하게 좋은 조언이지만 분명히이 특별한 문제의 원인이되지는 않는다. –

+0

이것이 문제의 근본 원인이 아니라는 것을 어떻게 알 수 있습니까? –

+0

NSObject에서 상속 받고 있기 때문입니다. 그 이유는 거의 확실하게 그가 코드에서 다른 위치의 배열에 다양한 점수 객체에 대한 다중 참조를 추가하고 있기 때문입니다. –

1

@selector(compare:)이 아닌 @selector(compareHighscore:)을 사용하여 정렬하려고합니다. 귀하의 의도는 이것입니다.

+0

죄송합니다. 오타입니다. 나는 실제로 compareHighscore를 호출 중입니다 ... –

0

시도
sortedArray = 최고 기록 sortedArrayUsingSelector : @ 선택기 (compareHighscore :)]; 나는 당신의 initWithCoder: 방법이 알았어 야

+0

죄송합니다. 오타입니다. 나는 실제로 compareHighscore를 호출하고있다. –

0

실제 compareHighscore : 메소드를 게시하십시오. 가장 중요한 것은 일치해야한다는 것인데, 즉 < = b이고 b가 < = c이면 < = c이고 <b 및 b <c이면 <c 일 경우입니다. 일관성이없는 비교 방법을 작성해도 문제가 발생할 수 있습니다.

관련 문제