在我的游戏中,我将玩家的统计数据保存在我存储在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!");
}
请帮助,我真的不明白什么是错的!我希望我已经足够清楚了!
答案 0 :(得分:0)
使用filepath而不是绝对路径。
答案 1 :(得分:0)
你的mac中可能存在重复项,这会使模拟器上的exists = true,但不会出现在设备上。
最简单的检查方法是NSLog遇到的路径。请参阅these tools - 它们允许为您设备上运行的发布版本捕获控制台日志。
答案 2 :(得分:0)
您的文档目录很可能不存在 - 在模拟器上,您与Mac上的所有人共享文档目录;在设备上每个人都有自己的目录。使用文件管理器方法
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.0/jquery.min.js"></script>
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>prop demo</title>
<style>
p {
margin: 20px 0 0;
}
b {
color: blue;
}
</style>
</head>
<body>
<input id="check1" type="checkbox" checked="checked">
<label for="check1">Check me</label>
<p></p>
<script>
$("input").change(function() {
var $input = $(this);
$("p").html(
".attr( \"checked\" ): <b>" + $input.attr("checked") + "</b><br>" +
".prop( \"checked\" ): <b>" + $input.prop("checked") + "</b><br>" +
".is( \":checked\" ): <b>" + $input.is(":checked")) + "</b>";
}).change();
</script>
</body>
</html>
在尝试编写目录之前确保目录存在。 (我倾向于使用URL方法而不是文件路径方法)。
PS。我建议使用一个方法返回您想要的路径或网址。不要一次又一次地复制代码是一个好习惯。
答案 3 :(得分:0)
我会做的很多,就像一次会议中的所有事情一样:
URL
; 应该是方法,我已经定义了一些宏来避免在代码中输入错误的文件名:
- (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
之后,您可以毫无问题地还原回文件,并且在运行时的其他时间点,您可以随时覆盖文件以方便使用。
注意:您可能需要扩展此代码以进行更详细的错误处理,我只在需要担心潜在错误时将注释放在位置。