2009-05-22 6 views
2

ハイスコアのplistファイルの読み書きを管理するためのより良い方法とは何か不思議でした。私のハイスコアのクラスがある:ハイスコアの永続性に関するアドバイス(iPhone、Cocoa Touch)

@interface HighScore : NSObject <NSCoding> { 
    NSString  *name; 
    int    score; 
    int    level; 
    int    round; 
    NSDate   *date; 
} 

さて、私は、方法Aを行うNSCodingのメソッドを追加することができます。でそれをすべてアウト

- (void) encodeWithCoder: (NSCoder *) coder { 
    [coder encodeObject: name 
       forKey: kHighScoreNameKey]; 
    [coder encodeInt: score 
       forKey: kHighScoreScoreKey]; 
    [coder encodeInt: level 
       forKey: kHighScoreLevelKey]; 
    [coder encodeInt: round 
       forKey: kHighScoreRoundKey]; 
    [coder encodeObject: date 
       forKey: kHighScoreDateKey]; 
} // encodeWithCoder 

- (id) initWithCoder: (NSCoder *) decoder { 
    if (self = [super init]) { 
     self.name = [decoder decodeObjectForKey: kHighScoreNameKey]; 
     self.score = [decoder decodeIntForKey: kHighScoreScoreKey]; 
     self.level = [decoder decodeIntForKey: kHighScoreLevelKey]; 
     self.round = [decoder decodeIntForKey: kHighScoreRoundKey]; 
     self.date = [decoder decodeObjectForKey: kHighScoreDateKey]; 
    } 
    return (self); 
} // initWithCoder 

をし、書き込み:

if (![NSKeyedArchiver archiveRootObject:highScoresList toFile:path]) ... 

はに戻ってそれを読みますかなりまっすぐ進むだろう。しかし、plistファイルIMHOはうんざりのように見えます。

または私は方法B採用できます

NSMutableArray *array = [NSMutableArray arrayWithCapacity:20];; 
for (HighScore *hs in highScoresList) { 
    NSDictionary *dict = [[NSDictionary alloc] initWithObjectsAndKeys: 
          hs.name, kHighScoreNameKey, 
          [NSNumber numberWithInteger:hs.score], kHighScoreScoreKey, 
          [NSNumber numberWithInteger:hs.level], kHighScoreLevelKey, 
          [NSNumber numberWithInteger:hs.round], kHighScoreRoundKey, 
          hs.date, kHighScoreDateKey, 
          nil]; 
    [array addObject:dict]; 
    [dict release]; 
} 

をし、それをすべて書き出し:

if (![array writeToFile:path atomically:YES]) ... 

後ろにそれを読むには、ほんの少し困難です。しかし、plistファイルはもっときれいに見えます(小さくてコンパクト)。

どのような考えですか?はるかに簡単なものがありますか? (ハイスコアをNSUserDefaultsとは別にして、それを使用しないようにしたい)

答えて

0

私はので、方法Bと一緒に行きました:私は簡単にこのメソッドに番号付けいくつかのファイルとクラスのバージョンをオフに保存することができますplistファイルをより読みで1と2:

私のハイスコアクラスで:

- (id)initFromDictionary: (NSDictionary *)dict; 
{ 
    if (self = [super init]) { 
     self.name = [dict objectForKey:kHighScoreNameKey]; 
     self.score = [[dict objectForKey:kHighScoreScoreKey] integerValue]; 
     self.game = [[dict objectForKey:kHighScoreGameKey] integerValue]; 
     self.level = [[dict objectForKey:kHighScoreLevelKey] integerValue]; 
     self.date = [dict objectForKey:kHighScoreDateKey]; 
    } 
    return (self); 
} 
- (NSDictionary *)putIntoDictionary; 
{ 
    NSDictionary *dict = [[NSDictionary alloc] initWithObjectsAndKeys: 
          name, kHighScoreNameKey, 
          [NSNumber numberWithInt:score], kHighScoreScoreKey, 
          [NSNumber numberWithInt:game], kHighScoreGameKey, 
          [NSNumber numberWithInt:level], kHighScoreLevelKey, 
          date, kHighScoreDateKey, 
          nil]; 
    return dict; 
} 

And in my HighScoreTable class: 
- (id) load 
{ 
    NSString *path = [self getFilePath]; 

// [self clear]; 
    NSDictionary *rootLevelPlistDict = [NSDictionary dictionaryWithContentsOfFile:path]; 
    int versNum = [[rootLevelPlistDict objectForKey:kHighScoreVersKey] integerValue]; 

    if (versNum == kHighScoreVersNum) { 
     NSArray *insideArray = [rootLevelPlistDict objectForKey:kHighScoresKey]; 

     NSDictionary *dict; 
     for (dict in insideArray) { 
      HighScore *hs = [[HighScore alloc] initFromDictionary:dict]; 
      [highScoresList addObject:hs]; 
      [hs release]; 
     } 
    } 
    return sharedHighScoresSingleton; 
} 


- (void) save 
{ 
    if (!changed) 
     return; 
    NSString *path = [self getFilePath]; 
    NSMutableArray *array = [NSMutableArray arrayWithCapacity:kNumberOfHighScores]; 
    for (HighScore *hs in highScoresList) { 
     NSDictionary *dict = [hs putIntoDictionary]; 
     [array addObject:dict]; 
     [dict release]; 
    } 
    NSDictionary *rootLevelPlistDict = [[NSDictionary alloc] initWithObjectsAndKeys: 
      [[[NSBundle mainBundle] infoDictionary] 
       objectForKey:(NSString*)kCFBundleNameKey], kHighScoreAppNameKey, 
       [NSNumber numberWithInt:kHighScoreHeaderVersNum], kHighScoreHeaderVersKey, 
       [NSNumber numberWithInt:kHighScoreVersNum], kHighScoreVersKey, 
       [NSDate date], kHighScoreCreationKey, 
      array, kHighScoresKey, 
      nil]; 

    if (![rootLevelPlistDict writeToFile:path atomically:YES]) 
     NSLog(@"not successful in writing the high scores"); 
    [rootLevelPlistDict release]; 
} 
+0

実際、NSCodingメソッドは "+(NSInteger)version"クラスメソッドを使用してバージョン管理を行うこともできます。これは私のアプリでのアップグレードのやり方です。 –

1

どちらもあなたの方法は私には罰金見えるアプリの便利です。 3.0 OSにはCore Dataもありますが、保存したいのは1つのハイスコア値であれば余計かもしれません。

1

私はあなたの反対を理解することはできません!どちらもうまくいくはずです。

私は個人的に方法Aを好みます。オブジェクトがそれ自身をエンコードする方法を知っていることは意味があると思います。メンテナンスが容易になり、すべての変更がローカライズされます。さらに、メモリ使用量も少なくなります。