【问题标题】:Writing and Reading from a plist file从 plist 文件中写入和读取
【发布时间】:2012-04-11 00:39:06
【问题描述】:

我目前需要读取和写入 plist 文件。 这是我目前的状态: 我创建了一个名为“Scores.plist”的 plist 文件,并将它放在我的 xcode 项目的 Resources 文件夹中。 plist 文件中包含一个带有键“Score”的字典。附加到键的对象是一个占位符值为 1010 的 NSNumber。 当我运行我的代码时,我得到了奇怪的结果。 我的 plist 是不是放错了地方? 我听说 plist 应该位于某些文档目录中,用于读写。但是,我不确定它到底在哪里。 任何帮助表示赞赏。提前致谢! :)

-(void)writeToPlistHighScore:(int)scoreNumber {  
    //attempt to write to plist   
    //however both the nslog's in this first section result in "null"
    NSString *documentsDirectory = [NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES) objectAtIndex:0];
    NSString *filePath = [documentsDirectory stringByAppendingPathComponent:@"Scores.plist"];

//NSString *scorePath2 = [[NSBundle mainBundle] pathForResource:@"Scores" ofType:@"plist"];
NSDictionary *plistDict = [[NSDictionary dictionaryWithContentsOfFile:filePath] retain];
NSLog(@"%@",[plistDict objectForKey:@"Score"]);
[plistDict setObject:[NSNumber numberWithInt:scoreNumber] forKey:@"Score"];
[plistDict writeToFile:filePath atomically: YES];
NSLog(@"%@",[plistDict objectForKey:@"Score"]);
[plistDict release];

//Stable code for reading out dictionary data
//this code reads out the dummy variable in Scores.plist located in my resources folder.
// Path to the plist (in the application bundle)
NSString *scorePath = [[NSBundle mainBundle] pathForResource:@"Scores" ofType:@"plist"];
NSDictionary *plistData = [[NSDictionary dictionaryWithContentsOfFile:scorePath] retain];
NSString *scoreString = [NSString stringWithFormat:@"Score:%@", [plistData objectForKey:@"Score"]];
NSLog(@"%@",scoreString);

//checking to see where my file is...
//this logs a file path which I don't know means
NSError *error;
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory2 = [paths objectAtIndex:0];
NSString *path = [documentsDirectory2 stringByAppendingPathComponent:[NSString stringWithFormat:@"%@.plist",@"Scores"]]; 

NSFileManager *fileManager = [NSFileManager defaultManager];

if (![fileManager fileExistsAtPath: path]){
    NSLog(@"File don't exists at path %@", path);

    NSString *plistPathBundle = [[NSBundle mainBundle] pathForResource:@"Scores" ofType:@"plist"];

    [fileManager copyItemAtPath:plistPathBundle toPath: path error:&error]; 
}else{
    NSLog(@"File exists at path:%@", path);
}

}

【问题讨论】:

    标签: objective-c ios cocos2d-iphone plist


    【解决方案1】:

    简短的回答是您想使用 NSDocumentDirectory 而不是 NSLibraryDirectory。

    NSString *documentsDirectory = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
    

    您希望保存到沙箱内的应用程序文档目录,而不是应用程序包。不允许在运行时更改应用程序包中的任何内容。

    请参阅http://developer.apple.com/library/mac/#documentation/FileManagement/Conceptual/FileSystemProgrammingGUide/FileSystemOverview/FileSystemOverview.html 了解完整说明。

    现在的窍门是,如果您想加载一个尚未保存的默认 plist 文件怎么办?好吧,首先检查您的文档目录,如果没有文件保存在那里,然后从您的资源目录加载模板。更好的是,如果它看起来像一个简单的结构,只需在代码中创建 NSDictionary,然后使用 writeToFile:atomically: 保存它,它将以 plist 格式写入。

    http://developer.apple.com/library/ios/#documentation/Cocoa/Conceptual/PropertyLists/QuickStartPlist/QuickStartPlist.html#//apple_ref/doc/uid/10000048i-CH4-SW5 对 plist 处理有很好的解释。它使用 Mac OS X 应用程序作为示例,但概念可以转移到 iOS。

    顺便说一句,您在保留和发布方面采取了一些不必要的步骤。 dictionaryWithContentsOfFile 创建一个自动释放的对象,因此不需要保留它,因此完成后不需要释放它。您可以使用以下代码完成与您在第一个代码块中所做的相同的事情:

    NSDictionary *plistDict = [NSDictionary dictionaryWithContentsOfFile:filePath]; 
    NSLog(@"%@",[plistDict objectForKey:@"Score"]); 
    [plistDict setObject:[NSNumber numberWithInt:scoreNumber] forKey:@"Score"]; 
    [plistDict writeToFile:filePath atomically: YES]; 
    NSLog(@"%@",[plistDict objectForKey:@"Score"]);
    

    plistDict 将在当前运行循环迭代时自动释放。我提到这一点是因为您在示例中稍后未能释放 plistData,如果稍后没有释放它,这是内存泄漏,而您可以通过不保留 plistData 来避免这种情况。有关自动释放对象的详细说明,请参阅 https://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/MemoryMgmt/Articles/mmAutoreleasePools.html#//apple_ref/doc/uid/20000047-CJBFBEDI

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多