在plist中更新和保存数据

我正在制作一款iOS游戏,需要保存玩家所达到的最高等级。 我可以成功更改plist中的数据元素,但由于某种原因,每次游戏重新启动时,该数据都会恢复为原始值。 这是我的代码的基本流程:

在游戏的初始化中,获得玩家达到的最高等级(原始值为1)

pData = [[PlayerData alloc] init]; currentLevel = [[pData.data valueForKey:@"Highest Level"] intValue]; [self startNewLevel:currentLevel]; 

‘data’是一个NSMutableDictionary,它在PlayerData中被初始化为:

 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] 

我知道这一切都有效,因为我有一个玩家在玩游戏时可以访问的关卡菜单。 每次玩家按下关卡菜单按钮时,都会创建一个UITableView的子类,显示级别1到达最高级别。 初始化如下所示:

 levelMenu = [[LevelMenu alloc] init:[[pData.data valueForKey:@"Highest Level"] intValue]]; 

水平菜单在游戏中显示正确的等级数(例如,如果玩家没有击败任何等级并进入等级菜单,则只显示“等级1”;但如果玩家击败等级1并进入级别菜单,显示“级别1”和“级别2”)。 但是,每当应用程序被终止或用户退出游戏主菜单时,“最高级别”的值将恢复为1并且此代码:

 currentLevel = [[pData.data valueForKey:@"Highest Level"] intValue]; 

无论用户在比赛中击败多少级别,总是在玩家按下开始时将currentLevel设置为1。

为什么价值会改变? 我错过了一些会让我的编辑永久性的东西吗?

编辑:

这是我新的’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; } 

从plist创建字典的最简单方法是使用方法dictionaryWithContentsOfFile : ,

例如,要从资源加载plist:

 NSString *filePath = [[NSBundle mainBundle] pathForResource:@"playerData" ofType:@"plist"]; NSMutableDictionary *plistdict = [NSMutableDictionary dictionaryWithContentsOfFile:filePath]; 

写一个plistdict同样简单:

 [plistdict writeToFile:filePath atomically:YES]; 

请注意 ,您无法写入应用程序的资源,因此您必须创建不同的路径,例如在plist的Documents目录中。

 NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); NSString *basePath = ([paths count] > 0) ? [paths objectAtIndex:0] : nil; NSString *docfilePath = [basePath stringByAppendingPathComponent:@"playerData.plist"]; [plistdict writeToFile:docfilePath atomically:YES]; 

现在再次从plist中检索数据。

  NSMutableDictionary *plistdict = [NSMutableDictionary dictionaryWithContentsOfFile:docfilePath]; 

在plistDict中添加内容并重新编写。

方法writeToFile:atomically返回BOOL结果。 我猜文件根本没有保存。

你的游戏正常工作的原因是因为应用程序从Dictionary读取数据(在启动时填充一次),而不是每次直接从plist文件中读取数据(并且它也不应该)。

检查以查看writeToFile:atomically方法的返回值,以确定文件是否实际被保存。

Interesting Posts