For a little iPhone application I am making, I want to sort a NSMutableArray.
I found 2 ways of doing this, but they both result in the same thing. Sorting the array will cause some objects to ‘overwrite’ eachother.
First off, here is my code:
AppDelegate.h
NSMutableArray* highScores;
Somewhere down that AppDelegate.h, I also make this variable a property so that I can access it from differen classes:
@property (retain, nonatomic) NSMutableArray* highScores;
When my application starts, I read the high scores from a file and import them into my NSMutableArray.
AppDelegate.m
NSMutableData* data = [NSData dataWithContentsOfFile:highScoresPath];
NSKeyedUnarchiver* decoder = [[NSKeyedUnarchiver alloc] initForReadingWithData:data];
self.highScores = [decoder decodeObjectForKey:@"highscoresArray"];
The objects I store in this NSMutableArray are from the type 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
Now, when I try to sort my array by using the following code:
NSArray *sortedArray;
sortedArray = [highScores sortedArrayUsingSelector:@selector(compareHighscore:)];
It somehow screws up my highScores array, I get an X amound of highscores with the same score and name.
What am I doing wrong?
I’m noticing that in your
initWithCoder:method, you’re not doing this:Same with your regular
initmethod. There needs to be a call to[super init].Also, since you defined your string properties as
copyand you’re using the property syntax, there’s no need toretainthem. They will be retained for you by the synthesized accessor.Otherwise, your code looks fine to me. Just remember: every
initmethod must always have a call to asuper‘sinit...method.