NSDictionary写入文件失败,即使对象是有效的,权限也是0k。

4

为什么无法写入NSDictionary?我检查了字典的内容:所有实例都是NSStringNSNumber。我检查了权限:同一路径下同名的文本文件已经成功写入。当然,我的字典不为空。

NSString *file = ...
NSDictionary *dict = ...

// check dictionary keys
BOOL wrong = NO;
for (id num in [dict allKeys]) {
    if (![num isKindOfClass:[NSNumber class]]) {
        wrong = YES;
        break;
    }
}
if (wrong) {
    NSLog(@"First");
}
// check dictionary values
wrong = NO;
for (id num in [dict allValues]) {
    if (![num isKindOfClass:[NSString class]]) {
        wrong = YES;
        break;
    }
}
if (wrong) {
    NSLog(@"Second");
}

if (![dict writeToFile:file atomically:YES]) {
    // 0k, let's try to create a text file
    NSLog(@"Names writing error!");
    [@"Something here... .. ." writeToFile:file atomically:YES encoding:NSUTF8StringEncoding error:nil];
}

输出:“名称书写错误!”
文本文件已成功创建。

你要把它写在哪里?在Bundle里吗?如果是这样,在iOS上你不能这样做,至少要写在一个新的文件路径下。 - Larme
@Larme 在 Mac OS 桌面上的一个文件夹中。 - AivanF.
2个回答

6
将字典写出会创建一个属性列表,根据 文档 ,属性列表中所有键必须是字符串
虽然NSDictionary和CFDictionary对象允许其键为任何类型的对象,但如果键不是字符串对象,则集合不是属性列表对象。
不支持将NSNumber对象作为键。

2
正如@vadian所指出的那样,您不能使用数字键编写plist。但是您可以使用NSKeyedArchiver:
NSURL *documents = [[NSFileManager defaultManager] URLForDirectory:NSDocumentDirectory inDomain:NSUserDomainMask appropriateForURL:nil create:false error:nil];
NSURL *fileURL = [documents URLByAppendingPathComponent:@"test.plist"];

// this will not work

NSDictionary *dictionary = @{@1: @"foo", @2: @"bar"};
BOOL success = [dictionary writeToFile:fileURL.path atomically:true];
NSLog(@"plist %@", success ? @"success" : @"failure");

// this will

fileURL = [documents URLByAppendingPathComponent:@"test.bplist"];
success = [NSKeyedArchiver archiveRootObject:dictionary toFile:fileURL.path];
NSLog(@"archive %@", success ? @"success" : @"failure");

您可以使用NSKeyedUnarchiver将其读取回来:

// to read it back

NSDictionary *dictionary2 = [NSKeyedUnarchiver unarchiveObjectWithFile:fileURL.path];
NSLog(@"dictionary2 = %@", dictionary2);

请注意,您可以使用符合(并正确实现)NSCoding的任何类来执行此操作。幸运的是,NSDictionary已经符合要求。您必须确保字典内部的任何对象也符合要求(NSStringNSNumber都是)。如果您的字典中有自定义对象,则必须自己使其符合要求。
所有这些内容都在归档和序列化编程指南中有详细描述。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接