Iphone writeToFile:原子性:不适用于4.1 SDK及以下版本,但适用于4.2 beta SDK

Iphone writeToFile:原子性:不适用于4.1 SDK及以下版本,但适用于4.2 beta SDK,iphone,Iphone,我使用以下代码写入plist(假设dict已经填充): 在我的应用程序中,代理的位置: - (NSString *)dataFilePath { NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); NSString *documentsDirectory = [paths objectAtIndex:0]; return [doc

我使用以下代码写入plist(假设dict已经填充):

在我的应用程序中,代理的位置:

- (NSString *)dataFilePath {
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *documentsDirectory = [paths objectAtIndex:0];
    return [documentsDirectory stringByAppendingPathComponent:kFilename];
}
我使用以下命令从磁盘读取plist:

NSMutableDictionary *dict = [[NSMutableDictionary alloc] initWithContentsOfFile:[appDelegate dataFilePath]];
在为4.2编译我的应用程序时,它起了作用,但由于我将其下载到4.1进行分发,它停止了工作

[dict writeToFile:[appDelegate dataFilePath] atomically:YES];

返回否。这里出了什么问题?

我猜其他一些更改会导致字典中出现非plist类型的对象。查看如果您将“生成plist”和“写入plist”步骤分开会发生什么:


好吧,现在我意识到它与基本SDK无关。我清理了所有目标,现在问题随处可见。我尝试切换到使用NSUserDefaults而不是writeToFile:atomically:,同样的问题也发生了。我不明白这里怎么了

如果NSUserDefaults不起作用,您的字典中很可能有不符合NSCoding的对象。 您可以使用类似的方法来找出是哪个键导致了这种情况。当然,你也必须检查你的价值观

for (id object in [dict allKeys])
    if (![object conformsToProtocol:@protocol(NSCoding)])
        NSLog(@"not NSCoding: %@ [%@]", object, [object class]);

iOS 4.2是一个测试版,除了苹果自己的论坛,你不允许在任何其他地方讨论它。我知道。但从那时起,我意识到这与SDK版本差异毫无关系。
/* Generate plist. */
NSError *error = nil;
NSData *data = [NSPropertyListSerialization
                dataFromPropertyList:dict
                format:NSPropertyListBinaryFormat_v1_0
                options:0/*unused*/
                error:&error];
if (!data) {
    NSLog(@"%s: Failed to serialize data: %@", __func__, error);
    return;
}

/* Write data. */
NSString *path = [appDelegate dataFilePath];
BOOL ok = [data writeToFile:dataFilePath options:NSDataWritingAtomic error:&error];
if (!ok) {
    NSLog(@"%s: Failed to write atomically to path %@: %@", __func__, path, error);
}
for (id object in [dict allKeys])
    if (![object conformsToProtocol:@protocol(NSCoding)])
        NSLog(@"not NSCoding: %@ [%@]", object, [object class]);