我试图在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>
* 由于未捕获的异常终止应用&#39; NSRangeException&#39;,原因:&#39; - [__ NSCFArray objectAtIndex:]:index(1)超出bounds(1)&# 39;
我添加了&#34;描述&#34;在写入plist之前到数组。如果我使用以下代码:
NSString *aDocumentsDirectory = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
// NSString *aFilePath = [NSString stringWithFormat:@"%@/Comments.plist", aDocumentsDirectory];
//
// NSMutableArray *plistArray = [[NSMutableArray alloc] initWithContentsOfFile:aFilePath];
返回值为(null)
但如果我使用:
NSString *filePath = [[NSBundle mainBundle] pathForResource:@"Comments" ofType:@"plist"];
NSMutableArray *plistArray = [[NSMutableArray alloc] initWithContentsOfFile:filePath];
我可以看到数组的内容,并且它们都能正常工作。
问题是:在两种方式中我都无法写入文件,它会一直返回&#34; NO&#34;。我已经检查了权限
答案 0 :(得分:3)
您正在尝试将文件写入 mainBundle 。绝对不可能。 您必须将plist文件写入应用程序的文档或应用程序支持文件夹。
在文档目录中创建文件路径:
NSString *aDocumentsDirectory = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
NSString *aFilePath = [NSString stringWithFormat:@"%@/Comments.plist", aDocumentsDirectory];
写入FilePath
[plistArray writeToFile:aFilePath atomically:YES];
从FilePath读取
NSMutableArray *plistArray = [[NSMutableArray alloc] initWithContentsOfFile:aFilePath];
答案 1 :(得分:0)
我发现您的代码有两个问题:
(可能是也可能不是问题)。如果该文件最初不存在,initWithContentsOfFile:
选择器将返回nil,导致其余代码为no-ops。
(可能是原因)。您可以不写入捆绑资源目录。将文件存储在Documents或Caches目录中。
要找到您的文档目录,请使用以下内容:
- (NSString*) pathForDocument:(NSString*)documentName {
NSArray *documentDirectories = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
if(documentDirectories.count < 1) return nil;
return [[documentDirectories objectAtIndex:0] stringByAppendingPathComponent:documentName];
}
答案 2 :(得分: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位置改为除你的捆绑以外的其他地方,我高度推荐。
答案 3 :(得分:-2)
如果您只在数组中放入一个项目,那么在读取数据时,您应该使用索引0而不是1:
NSMutableDictionary *dictionary = (NSMutableDictionary *) [plistArray objectAtIndex:0];