对于我正在制作的小型iPhone应用程序,我想对NSMutableArray进行排序。
我找到了两种方法,但它们都会产生同样的结果。对数组进行排序会导致某些对象相互“覆盖”。
首先,这是我的代码:
AppDelegate.h
NSMutableArray* highScores;
在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数组,我获得了一个具有相同分数和名称的X高分数。
我做错了什么?
答案 0 :(得分:1)
您尝试使用@selector(compare:)
排序,而不是@selector(compareHighscore:)
,我认为这是您的意图。
答案 1 :(得分:1)
我注意到,在你的initWithCoder:
方法中,你没有这样做:
if (self = [super initWithCoder:coder]) {
// Decode your stuff here
}
与常规init
方法相同。需要拨打[super init]
。
此外,由于您将字符串属性定义为copy
并且您使用的是属性语法,因此无需retain
它们。它们将由合成访问器保留给您。
否则,您的代码对我来说很好。请记住:每个init
方法都必须始终调用super
的{{1}}方法。
答案 2 :(得分:0)
答案 3 :(得分:0)
发布实际的compareHighscore:方法。最重要的是它必须是一致的,即如果a <= b且b <= c,则a&lt; = c并且如果a&lt; = b和b&lt;然后a&lt; C。如果你设法编写一个不一致的比较方法,任何事情都可能发生。