【问题标题】:NSArray writeToFile failsNSArray writeToFile 失败
【发布时间】:2010-06-09 22:11:34
【问题描述】:

我正在尝试将包含一些字典的数组保存到 plist 文件中,但它失败了。我没有收到任何错误。我在代码中使用另一个数组执行了完全相同的几行代码,并且可以正常工作。我不知道为什么它不保存文件。

这是我保存文件的地方:(请参阅下面的一些调试器输出)

// When built parse through dictionary and save to file
    for ( NSString *keys in [dicByCountry allKeys] )
    {
        NSArray *arrr = [[NSArray alloc] initWithArray:[dicByCountry objectForKey:keys]];
        NSString *fname = [self filePath:[NSString stringWithFormat:@"regions.cid%@.plist",keys]];
        if (![arrr writeToFile:fname atomically:YES])
            NSLog(@"Could not write file regions.cid%@.plist",keys);
    }

这里有一些 GDB 输出

(gdb) po fname
/Users/chris/Library/Application Support/iPhone Simulator/4.0/Applications/44A9FF9E-5715-4BF0-9BE2-525883281420/Documents/regions.cid0.plist


(gdb) po arrr
<__NSArrayI 0x8022b30>(
{
    countryID = "<null>";
    region = "?\U00e2vora";
    regionID = 16;
},
{
    countryID = "<null>";
    region = Vicenza;
    regionID = 14;
},
{
    countryID = "<null>";
    region = Wales;
    regionID = 23;
}
)

【问题讨论】:

    标签: iphone file nsarray


    【解决方案1】:

    如果您仔细阅读the documentationwriteToFile:atomically: 期望该数组仅包含可写入 plist 文件的对象。

    仅对象类型:

    • NSString
    • NSData
    • NSDate
    • NSNumber
    • NSArray
    • NSDictionary

    是允许的。如果您保存的数组中有数组或字典,它们的值将按照相同的标准进行检查。

    这比NSArrays 通常允许的要严格一些。特别是,值[NSNull null] 是不可接受的。

    【讨论】:

    • NSNumber 呢?零呢?
    • 数组不能包含 nil 并且文档没有表明 NSNumber s 作为属性列表值是有效的。
    • 所以数组不能包含任何自定义对象?
    • 它可以包含一个已序列化为 NSData 的自定义对象。同样,writeToFile 方法的前提条件是数组与属性列表文件完全同构,这非常严格地限制了包含的数据类型。
    【解决方案2】:

    我在序列化之前将 NSArray 或 NSDictionary 转换为 NSData。以下是用于序列化和反序列化的 nsarray 类别。这很舒服,可以处理一些 nsnull 的数据

    @implementation NSArray(Plist)
    
    -(BOOL)writeToPlistFile:(NSString*)filename{
        NSData * data = [NSKeyedArchiver archivedDataWithRootObject:self];
        NSArray * paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
        NSString * documentsDirectory = [paths objectAtIndex:0];
        NSString * path = [documentsDirectory stringByAppendingPathComponent:filename];
        BOOL didWriteSuccessfull = [data writeToFile:path atomically:YES];
        return didWriteSuccessfull;
    }
    
    +(NSArray*)readFromPlistFile:(NSString*)filename{
        NSArray * paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
        NSString * documentsDirectory = [paths objectAtIndex:0];
        NSString * path = [documentsDirectory stringByAppendingPathComponent:filename];
        NSData * data = [NSData dataWithContentsOfFile:path];
        return  [NSKeyedUnarchiver unarchiveObjectWithData:data];
    }
    
    @end //needs to be set for implementation
    

    【讨论】:

    • 我在 NSDictionary 上使用了这段代码,效果很好。谢谢!
    • 我有一个自定义类,它有许多不同的属性(NSIntegerBOOL 等),存储在NSArray 中。 [NSArray writeToFile:atomically:] 不起作用,但使用 NSKeyedArchiver 将根对象(NSArray)转换为 NSData 确实有效!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-08-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多