1

我正在尝试在 plist 中保存一些评论,这没关系,因为它只是一个原型。问题是我可以从 plist 中读取,但是当我尝试在此之后写入和读取时,它会引发“数组越界”异常。我无法弄清楚我在这里做错了什么。

NSString *filePath = [[NSBundle mainBundle] pathForResource:@"Comments" ofType:@"plist"];
NSMutableArray *plistArray = [[NSMutableArray alloc] initWithContentsOfFile:filePath];


NSMutableDictionary *newComment = [NSMutableDictionary dictionary];
[newComment setValue:commentTitle.text forKey:@"title"];
[newComment setValue:comment forKey:@"comment"];


[plistArray addObject:newComment];
[plistArray writeToFile:filePath atomically:NO];

效果很好,然后我尝试阅读:

NSString *filePath = [[NSBundle mainBundle] pathForResource:@"Comments" ofType:@"plist"];
NSMutableArray *plistArray = [[NSMutableArray alloc] initWithContentsOfFile:filePath];


NSMutableDictionary *dictionary = (NSMutableDictionary *) [plistArray objectAtIndex:0];

NSLog(@"%@", [dictionary objectForKey:@"title"]);

它抛出异常。

如果我手动将项目添加到 plist,它工作正常,我想这意味着我的阅读代码很好。

可能是我的 plist 的结构吗?

<?xml version="1.0" encoding="UTF-8"?>
 <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
 <plist version="1.0">
 <array>
 </array>
 </plist>

*由于未捕获的异常“NSRangeException”而终止应用程序,原因:“-[__NSCFArray objectAtIndex:]: index (1) beyond bounds (1)”

在写入 plist 之前,我将“描述”添加到数组中。如果我使用以下代码:

NSString *aDocumentsDirectory = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
//    NSString *aFilePath = [NSString stringWithFormat:@"%@/Comments.plist", aDocumentsDirectory];
//
//    NSMutableArray *plistArray = [[NSMutableArray alloc] initWithContentsOfFile:aFilePath];

返回为(空)

但如果我使用:

NSString *filePath = [[NSBundle mainBundle] pathForResource:@"Comments" ofType:@"plist"];
NSMutableArray *plistArray = [[NSMutableArray alloc] initWithContentsOfFile:filePath];

我可以看到数组的内容,并且一切正常。

问题是:在两种方式中我都无法写入文件,它一直返回“NO”。而且我已经检查了权限

4

4 回答 4

4

您正在尝试将文件写入mainBundle。绝对不可能。您必须将 plist 文件写入应用程序的DocumentsApplication Support文件夹。

在文档目录中创建文件路径:

NSString *aDocumentsDirectory = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];

NSString *aFilePath = [NSString stringWithFormat:@"%@/Comments.plist", aDocumentsDirectory];

写入文件路径

[plistArray writeToFile:aFilePath atomically:YES];

从文件路径读取

NSMutableArray *plistArray = [[NSMutableArray alloc] initWithContentsOfFile:aFilePath];
于 2012-07-26T12:37:57.840 回答
0

首先,你为什么要在你的包中写入一个文件?

然后,为了解决您的问题,请检查您是否确实编写了该文件。

if ([plistArray writeToFile:filePath atomically:NO])
    NSLog (@"Written");
else
    NSLog (@"Not Written");

此外,在您阅读数组时记录您的数组,-(void)description以检查字典的内容。

编辑

正如你所说,你没有写信给你的 plist。现在,只需在您的桌面上创建一个测试 plist。

NSString *testPath = [[NSString stringWithString:@"~/Desktop/Comments.plist"] stringByExpandingTildeInPath];
if ([plistArray writeToFile:testPath atomically:NO])
    NSLog (@"Written");
else
    NSLog (@"Not Written");    

如果仍然返回 Not Written,那么您的字典有问题。我对此表示怀疑,因为它只是字符串(尽管它们可能是在 stackoverflow 上询问您的问题的占位符。文档指出字典中的类必须是 NSData、NSDate、NSNumber、NSString、NSArray 或 NSDictionary)。如果那说写了,我猜它不会因为权限而写入您的包,那么您必须将您的 plist 位置更改为您的包以外的其他位置,我强烈建议您这样做。

于 2012-07-26T12:09:43.800 回答
0

我发现您的代码有两个问题:

  1. (可能是也可能不是问题)。如果文件最初不存在,则initWithContentsOfFile:选择器将返回 nil,从而导致其余代码无操作。

  2. (可能是原因)。您可能不会写入捆绑资源目录。将您的文件存储在 Documents 或 Caches 目录中。

要找到您的文档目录,请使用以下内容:

- (NSString*) pathForDocument:(NSString*)documentName {
    NSArray *documentDirectories = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    if(documentDirectories.count < 1) return nil;
    return [[documentDirectories objectAtIndex:0] stringByAppendingPathComponent:documentName];
}
于 2012-07-26T12:05:29.730 回答
-2

如果您只在数组中放置一项,则在读取时显然应该使用索引 0 而不是 1:

NSMutableDictionary *dictionary = (NSMutableDictionary *) [plistArray objectAtIndex:0];
于 2012-07-26T12:00:39.427 回答