对象有效时 NSDictionary writeToFile 失败,权限为 0k

NSDictionary writeToFile fails while objects are valid, permission is 0k

为什么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];
}

输出:"Names writing error!"
文本文件创建成功。

写出字典会创建一个 属性 列表,并且根据 documentation 属性 列表中的所有键必须是 strings .

... and although NSDictionary and CFDictionary objects allow their keys to be objects of any type, if the keys are not string objects, the collections are not property-list objects.

NSNumber 不支持作为键的对象。

正如@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 的 class 来执行此操作。幸运的是,NSDictionary 已经符合。您必须确保字典中的任何对象也符合(NSStringNSNumber 都符合)。如果您的字典中有一个自定义对象,您必须自己使其正确符合。

这在Archives and Serializations Programming Guide.

中都有描述