0

在我的游戏中,我将玩家的统计数据保存在我存储在 Documents 目录中的 plist 中。我有一个应该保存的每个统计信息的空字典,命名为“Default_Stats.plist”,这样如果这是第一次加载应用程序,它会将其复制到适当的目录中,以便可以随意加载和覆盖。问题是,每次加载我的应用程序时,它都无法识别“Stats.plist”并用默认统计数据覆盖它,重置玩家所做的每个统计数据......而且很奇怪,它完美地工作在模拟器,但不在设备上。这是我的代码:

在这种方法中,我阅读了统计数据:

- (void) readStatsFromFile{
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *statsPath = [[paths objectAtIndex:0] stringByAppendingPathComponent:@"Stats.plist"];

    //Check if the file has already been created
    if (![[NSFileManager defaultManager] fileExistsAtPath:statsPath]){
        [self createStatsList];
    }else{
        stats = [[NSMutableDictionary dictionaryWithContentsOfFile:statsPath]retain];
    }
}

这是我的创建方法:

- (void) createStatsList{
    NSString *statsPath = [[NSBundle mainBundle] bundlePath];
    statsPath = [statsPath stringByAppendingPathComponent:@"Default_Stats.plist"];

    stats = [[NSMutableDictionary dictionaryWithContentsOfFile:statsPath] retain];

    [self writeStatsToFile];
}

还有我的写作方法:

- (void) writeStatsToFile{
    BOOL ok;
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *statsPath = [[paths objectAtIndex:0] stringByAppendingPathComponent:@"Stats.plist"];
    ok = [stats writeToFile:statsPath atomically:YES];

    if (!ok) {
        NSLog(@"Couldn't write to file");
    }else
        NSLog(@"Stats written succesfully!");
}

请帮忙,我真的不明白这是怎么回事!我希望我已经把自己说得够清楚了!

4

4 回答 4

0

也许你的mac中存在重复,这使得exists=true在模拟器上,而不是在设备上。

最简单的检查方法是 NSLog 遇到的路径。请参阅这些工具- 它们允许为在您的设备上运行的发布版本捕获控制台日志。

于 2013-01-07T18:38:51.603 回答
0

使用文件路径而不是绝对路径。

于 2013-01-07T16:08:12.930 回答
0

我会做很多事情,就像一个会话中的所有内容一样:

  1. 获取DocumentURL文件夹中的文件;
  2. 如果文件还没有,则将文件从bundle复制到Documents文件夹;

那应该是方法,我已经定义了一些宏来避免在代码中输入错误的文件名:

- (NSURL *)statsFileURL {
#define NSStringFromFileNameWithExtension(filename, extension) [(filename) stringByAppendingPathExtension:(extension)]
#define kExtension @"plist"
#define kDefaultStatsFileName @"Default_Stats"
#define kCustomStatsFileName @"Stats"

    NSURL *_returnURL = nil;

    NSFileManager *_fileManager = [NSFileManager defaultManager];
    NSURL *_documentDirectory = [[_fileManager URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject];
    NSURL *_myFileURLInDocumentFolder = [_documentDirectory URLByAppendingPathComponent:NSStringFromFileNameWithExtension(kDefaultStatsFileName, kExtension)];
    if ([_fileManager fileExistsAtPath:[_myFileURLInDocumentFolder path]]) {
        _returnURL = _myFileURLInDocumentFolder;
    } else {
        NSURL *_myFileURLInBundle = [[NSBundle mainBundle] URLForResource:kDefaultStatsFileName withExtension:kExtension];
        if ([_fileManager fileExistsAtPath:[_myFileURLInBundle path]]) {
            NSError *_error = nil;
            if ([_fileManager copyItemAtURL:_myFileURLInBundle toURL:_myFileURLInDocumentFolder error:&_error]) {
                if (_error == nil) {
                    _returnURL = _myFileURLInDocumentFolder;
                } else {
                    // some error during copying
                }
            } else {
                // some error during copying
            }
        } else {
            // the file does not esixts at all, not even in the bundle
        }
    }

    return _returnURL;
}

URL总是指向Documents文件夹内,因此您将具有对该文件的读/写访问权限 - 或者如果nil发生某些错误。

拥有 之后URL,您可以毫无问题地恢复到文件,并且在运行时的其他某个时间点,您可以随时覆盖该文件以方便您使用。


注意:您可能需要扩展此代码以进行更详细的错误处理,我只在您需要担心潜在错误的地方添加注释。

于 2015-12-18T09:39:25.230 回答
0

很可能您的文档目录不存在 - 在模拟器上,您与 Mac 上的每个人共享一个文档目录;在设备上,每个人都有自己的目录。使用文件管理器方法

createDirectoryAtURL:url withIntermediateDirectories:YES

在您尝试在那里写入之前确保该目录存在。(我倾向于使用 URL 方法而不是文件路径方法)。

PS。我建议使用一种方法来返回您想要的路径或 url。不要一次又一次地重复你的代码是一个好习惯。

于 2015-12-18T09:28:30.313 回答