NSKeyedArchiver写XML(或其他人类可读的)?

时间:2009-10-30 17:30:41

标签: objective-c cocoa

我一直试图让NSKeyedArchiver以人类可读的形式写出我的数据(即不是二进制文件)我知道我可以使用......

setOutputFormat: NSPropertyListXMLFormat_v1_0

但是......我似乎无法正确理解语法,有人能指出我正确的方向吗?

NSData *artistData;

NSLog(@"(*) - Save All");
artistData = [NSKeyedArchiver archivedDataWithRootObject:artistCollection ];
[artistData writeToFile:@"/Users/fgx/Desktop/stuff" atomically:YES];

修改

我添加了setOutputFormat(见下文)但是我在编译时收到警告,我错过了什么?

warning: NSData  may not respond to 'setOutputFormat:'

这是我使用的代码。

NSLog(@"(*) - Save All");
artistData = [NSKeyedArchiver archivedDataWithRootObject:artistCollection ];
[artistData setOutputFormat: NSPropertyListXMLFormat_v1_0];
[artistData writeToFile:@"/Users/fgx/Desktop/stuff" atomically:YES];

加里

4 个答案:

答案 0 :(得分:17)

这就是你要做的事情:

NSMutableData *data = [NSMutableData data];
NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc] initForWritingWithMutableData:data];
[archiver setOutputFormat:NSPropertyListXMLFormat_v1_0];
[archiver encodeObject:artistCollection forKey:@"root"];
[archiver finishEncoding];
[data writeToFile:@"/Users/fgx/Desktop/stuff" atomically:YES];
[archiver release];

请注意,必须使用[archiver encodeObject:artistCollection forKey:@"root"]代替[archiver encodeRootObject:artistCollection];,如Sean所建议的那样。这是因为NSKeyedArchiver不会覆盖NSCoder encodeRootObject:方法。我认为这是一个错误,并将其报告给Apple。

现在,真正的问题是为什么要编写XML而不是默认的二进制格式?如果是出于调试目的,我建议您使用TextWrangler,这样您就可以透明地编辑二进制plist文件,就好像它们是XML一样。

答案 1 :(得分:2)

您需要首先创建一个NSKeyedArchiver实例,而不是使用只返回NSData的方便类方法。

NSMutableData *data = [NSMutableData new];
NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc] initForWritingWithMutableData:data];

// set the one property you specifically wanted
[archiver setOutputFormat:NSPropertyListXMLFormat_v1_0];

// now encode (and finalize) the actual object - note that encodeRootObject: is inherited
// from NSCoder. I assume this works :)
[archiver encodeRootObject:artistCollection];
[archiver finishEncoding];

// now finally write it out - the resulting encoded stuff should be waiting in the data object
[data writeToFile:@"/Users/fgx/Desktop/stuff" atomically:YES];

// cleanup after ourselves
[archiver release];
[data release];

免责声明:我在此处的输入框中编写了此代码,并未对其进行实际测试。

答案 2 :(得分:1)

'archivedDataWithRootObject:'是一个类方法,而'setOutputFormat'是一个实例方法。来自'archivedDataWithRootObject:'的文档:

  

NSData对象,包含对象图的编码形式,其根对象是rootObject。存档的格式为NSPropertyListBinaryFormat_v1_0。

您需要做的是创建一个NSKeyedArchiver,并对根对象进行编码。另外,确保集合的所有内容都实现'encodeWithCoder'和'initWithCoder'。看到 Encoding and Decoding Objects

这种方法的问题是你必须为你编码的每个对象手动分配键,这听起来不像你想要的那样,因为你已经有了一个集合。 Arrays和Dictionaries都包含写入xml文件的方法,这是一种更容易的方法。

[artistCollection writeToFile:@"/Users/fgx/Desktop/stuff" atomically:YES];

讨论此方法(对于NSDictionary和NSArray):

  

如果接收者的内容都是属性列表对象(NSString,NSData,NSArray或NSDictionary对象),则此方法编写的文件可用于使用类方法arrayWithContentsOfFile:或实例方法initWithContentsOfFile初始化新数组: 。此方法在写出文件之前以递归方式验证所有包含的对象是属性列表对象,如果所有对象都不是属性列表对象,则返回NO,因为生成的文件不是有效的属性列表。   块引用

答案 3 :(得分:0)

[artistData setOutputFormat: NSPropertyListXMLFormat_v1_0];