【问题标题】:Saving Successfully, but not Visibly Editing plist保存成功,但不可见编辑 plist
【发布时间】:2014-03-22 11:51:20
【问题描述】:

所以这是我第一次尝试在 iOS 应用中保存数据。我已经从这个网站上的各种答案中拼凑出这段代码,以便为我正在制作的游戏保存高分。我创建了一个名为 saves.plist 的 plist(在我的 Supporting Files 文件夹中)并添加了一行键 @"bestScore" 并键入 Number。测试日志返回保存成功,一切正常;然而,当我去查看 plist 之后,似乎什么都没有改变(bestScore 的值为 0)。我是否保存到在我的代码中自动创建的不同 plist?如果是这种情况,那么能够在 Xcode 中创建 plist 有什么意义?就在哪里/如何创建/存储/访问 plist 而言,这里使用的最佳实践是什么?

@implementation ViewController

- (void)viewDidLoad
{
    [super viewDidLoad];

    self.fm = [NSFileManager defaultManager];

    self.destPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];//Documents directory
    self.destPath = [self.destPath stringByAppendingPathComponent:@"saves.plist"];

    // If the file doesn't exist in the Documents Folder, copy it.
    if (![self.fm fileExistsAtPath:self.destPath]) {
        NSString *sourcePath = [[NSBundle mainBundle] pathForResource:@"saves" ofType:@"plist"];
        [self.fm copyItemAtPath:sourcePath toPath:self.destPath error:nil];
    }
}

- (void)saveBestScore{
    NSNumber *bestScoreBox = [NSNumber numberWithUnsignedLong:self.bestScore];
    NSDictionary *data = @{bestScoreBox: @"bestScore"};

    BOOL successful = [data writeToFile:self.destPath atomically:YES];
    successful ? NSLog(@"YES") : NSLog(@"NO");
}

【问题讨论】:

    标签: ios objective-c plist


    【解决方案1】:

    当你说

    当我去查看 plist 之后,似乎什么都没有改变 (bestScore的值为0)

    您的意思是查看 xcode 项目文件中的 plist 吗?您已将 plist 复制到设备目录中,因此您将无法在 xcode 中看到更改。

    如果您使用的是模拟器,您可以在以下位置访问更改后的 plist:

    ~/Library/Application Support/iPhone Simulator/<Simulator Version>/Applications/<application>/Documents/
    

    存储分数的一种简单方法是使用 NSUserDefault,这是一个类似于字典的每个应用程序的持久存储。

    设定分数:

    NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
    [userDefaults setObject:@(score) 
                     forKey:@"score"];
    [userDefaults synchronize];
    

    获得分数:

    int score = [[[NSUserDefaults standardUserDefaults] objectForKey:@"score"] intValue];
    

    更新

    rmaddy 提到 NSUserDefaults 支持 setInteger:forKeyintegerForKey: 因此您不需要将分数包装到 NSNumber 中

    【讨论】:

    • 为什么不直接使用NSUserDefaults setInteger:forKey:NSUserDefaults integerForKey: 呢?无需装箱/拆箱。
    • 很好的答案,谢谢。所以基本上需要在 Xcode 项目文件中创建 plist 以便可以将其复制到设备目录中,但 Xcode 中的那个将保持不变?
    • 没错。您在 xcode 中创建的所有内容(代码和支持文件)都将在应用启动之前复制到设备/模拟器上。在那之后,该应用程序仅适用于设备上的本地副本。这就是为什么即使您关闭 xcode 或拔下 xcode 和设备之间的电缆,该应用程序也可以运行的原因。
    【解决方案2】:

    当您使用writeToFile:NSDictionary 写入plist 时,字典中的键和值必须遵循严格的规则。所有键必须是NSString 对象,所有值必须是属性值(NSStringNSNumberNSDateNSData 等)。

    您遇到的问题是您的字典有一个键是 NSNumber,而不是 NSString

    看来您实际上错误地创建了字典。语法是:

    @{ key : value, key : value, ... }
    

    将您的代码更改为:

    NSDictionary *data = @{ @"bestScore" : bestScoreBox }; // key : value
    

    旁注 - 你的最后一行应该是:

    NSLog(@"%@", successful ? @"YES" : @"NO");
    

    使用三元运算符运行两个不同的命令不是一个好习惯。它旨在返回两个值之一。

    【讨论】:

      猜你喜欢
      • 2017-09-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-12-23
      • 1970-01-01
      相关资源
      最近更新 更多