2009-05-22 26 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文件,恕我直言,看起來像廢話。

或者我可以使用方法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,因爲:1. plist文件是更具可讀性和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)版本」類方法進行版本控制。這是我用來在我的應用程序中進行升級的方式。 – 2009-07-02 20:22:37

1

無論你如何看沒什麼問題。在3.0操作系統中也有核心數據,儘管如果你想要保存的只是一個單獨的高分值,它可能會過度殺傷。

1

我不確定我瞭解你的反對意見!兩者都應該工作得很好。

我個人比較喜歡方法A.我認爲一個對象知道如何編碼自己是有道理的。它使維護更容易,任何更改都更加本地化。另外它可能會使用更少的內存。