iOS ゲームを作成しており、プレイヤーが到達した最高レベルを保存する必要があります。plist のデータ要素を正常に変更できますが、何らかの理由で、ゲームを再起動するたびにそのデータが元の値に戻り続けます。私のコードの基本的な流れは次のとおりです。
ゲームの初期化で、プレイヤーが到達した最高レベルを取得します (元の値は 1 です)。
pData = [[PlayerData alloc] init];
currentLevel = [[pData.data valueForKey:@"Highest Level"] intValue];
[self startNewLevel:currentLevel];
「data」は、PlayerData で次のように初期化される NSMutableDictionary です。
self.data = [NSMutableDictionary dictionaryWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"playerdata" ofType:@"plist"]];
後で、プレーヤーが最高レベルを破った場合、「最高レベル」の値をインクリメントし、PlayerData で次の関数を呼び出してファイルに書き込みます。
-(void) newHighestLevel:(NSString*)path :(int)level{
[self.data setValue:[NSNumber numberWithInt:level] forKey:path];
[self.data writeToFile:@"playerdata.plist" atomically:YES]
プレイヤーがゲームのプレイ中にアクセスできるレベル メニューがあるため、これがすべて機能していることはわかっています。プレーヤーがレベル メニュー ボタンを押すたびに、レベル 1 から到達した最高レベルまでを表示する UITableView のサブクラスが作成されます。初期化は次のようになります。
levelMenu = [[LevelMenu alloc] init:[[pData.data valueForKey:@"Highest Level"] intValue]];
レベル メニューには、ゲーム中に正しいレベル数が表示されます (たとえば、プレーヤーがレベルをクリアしていない状態でレベル メニューに移動した場合、「レベル 1」と表示されますが、レベル 1 をクリアしてレベル メニューに移動した場合は、レベルメニューでは、「レベル1」と「レベル2」が表示されます)。ただし、アプリが終了するか、ユーザーがゲームのメイン メニューを終了すると、「最高レベル」の値が 1 に戻り、次のコードが実行されます。
currentLevel = [[pData.data valueForKey:@"Highest Level"] intValue];
プレイヤーがスタートを押すと、ユーザーがプレイ中にいくつのレベルを破ったかに関係なく、常に currentLevel を 1 に設定します。
値が元に戻るのはなぜですか? plist の編集を永続的にする何かが欠けていますか?
編集:
ここに私の新しい「newHighestLevel」メソッドがあります:
-(void) newHighestLevel:(NSString*)path :(int)level{
[self.data setValue:[NSNumber numberWithInt:level] forKey:path];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *basePath = ([paths count] > 0) ? [paths objectAtIndex:0] : nil;
NSString *docfilePath = [basePath stringByAppendingPathComponent:@"playerdata.plist"];
[self.data writeToFile:docfilePath atomically:YES];
self.data = [NSMutableDictionary dictionaryWithContentsOfFile:docfilePath];
BOOL write = [self.data writeToFile:docfilePath atomically:YES];
}
write は YES に設定されます。「docfilePath」を @"playerdata.plist" に変更すると、NO に設定されます。どちらの場合も、ゲームで何も変わらないようです。
解決:
-(void) newHighestLevel:(NSString*)path :(int)level{
[self.data setValue:[NSNumber numberWithInt:level] forKey:path];
NSString *basePath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
NSString *docfilePath = [basePath stringByAppendingPathComponent:@"playerdata.plist"];
[self.data writeToFile:docfilePath atomically:YES];
}
そして初期化で
-(id) init{
NSString *basePath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
NSString *docfilePath = [basePath stringByAppendingPathComponent:@"playerdata.plist"];
NSFileManager *fileManager = [NSFileManager defaultManager];
if (![fileManager fileExistsAtPath:docfilePath]){
NSString *sourcePath = [[NSBundle mainBundle] pathForResource:@"playerdata" ofType:@"plist"];
[fileManager copyItemAtPath:sourcePath toPath:docfilePath error:nil];
}
self.data = [NSMutableDictionary dictionaryWithContentsOfFile:docfilePath];
return self;
}