2009-06-08 3 views
0

私が作っている小さなiPhoneアプリケーションでは、NSMutableArrayをソートしたいと思います。NSMutableArrayをカスタムオブジェクトでソートするといくつかのオブジェクトが上書きされます

私はこれを行う2つの方法を見つけましたが、どちらも同じことになります。配列をソートすると、いくつかのオブジェクトが互いに上書きされます。

まず第一に、ここに私のコードは次のとおりです。

AppDelegate.h

NSMutableArray* highScores; 

どこかでダウン私はdifferenからアクセスできるようにAppDelegate.hが、私もこの変数プロパティを作ることクラス:

私のアプリケーションが起動すると、ファイルからハイスコアを読み込み、それらをNSMutableArrayにインポートします。

AppDelegate.m

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

私はこのNSMutableArrayの中で保存したオブジェクトは型ハイスコ​​アからです。

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配列、私は同じスコアと名前で最高スコアのX amoundを取得します。

私は間違っていますか?

+0

これは実際にsortedArrayUsingSelectorの呼び出しによって引き起こされていることは確かですか?前と後の実際のhighScores配列を見てみましたか?あなたのコードのどこかに、重複したオブジェクトを挿入している可能性のあるhighScores配列にオブジェクトを追加することがありますか?覚えておいてください - これはセットではないので、同じハイスコアオブジェクトを複数回挿入すると配列内に複数回表示されますが、配列内のオブジェクト参照であるためスコアは常に同じになります。 –

+0

私は同意します。私はあなたの 'NSArray * sortedArray;行の直前にブレークポイントを置いて、次にgdbに配列を出力することをお勧めします:' po highScores' –

答えて

1

私はあなたのinitWithCoder:方法では、あなたがこれをやっていないことに気づい:あなたの定期的なinit方法と

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

同じ。 [super init]への電話が必要です。

また、文字列のプロパティをcopyと定義し、プロパティの構文を使用しているため、retainは不要です。それらは合成アクセッサによって保持されます。

そうしないと、コードが正常に見えます。ちょうど覚えておいてください:initメソッドは常にsuperinit...メソッドを呼び出す必要があります。

+0

これは明らかに一般的なアドバイスですが、この特定の問題の原因ではありません。 –

+0

これは彼の問題の根本的な原因ではないことをどう知っていますか? –

+0

彼はNSObjectから継承しているからです。この原因は、コード内の他の場所の配列に、さまざまなスコアオブジェクトへの複数の参照を追加していることがほぼ確実です。 –

1

@selector(compare:)を使用して並べ替えようとしていますが、あなたの意図は私が推測している@selector(compareHighscore:)ではありません。

+0

これは誤字です。私は実際にcompareHighscoreを呼び出しています.. –

0

を試みる
sortedArray =ハイスコアsortedArrayUsingSelector:@selector(compareHighscore:)]。

+0

私は申し訳ありません、それは誤字です。私は実際にcompareHighscoreを呼び出しています。 –

0

実際のcompareHighscore:メソッドを投稿してください。最も重要なことは、一貫していなければならないことです。すなわち、< = cの場合は< = c、<bの場合は<c、次に<cの場合は一貫していなければなりません。一貫性のない比較メソッドを作成できた場合は、何かが起こる可能性があります。

関連する問題