将数组保存到包含自定义对象iPhone的Plist文件

我有一个名为XYZinheritance自NSObject的类和一个包含XYZ对象的数组。 我需要将这个数组写入文档目录的plist文件。 在尝试[array writeToFile ….]之后,我发现writeToFile失败,因为数组包含XYZ类的自定义对象。

可能的解决scheme是将对象转换为NSData。 有什么不同的方式来实现这个? 我发现NSCoding是合适的,但不能理解如何使用它。 任何帮助将不胜感激。

Ray Wenderlich的博客上有一个很好的教程,解释了如何使用NSCoding。

只需要在对象中实现* – (void)encodeWithCoder:(NSCoder )编码和* – (id)initWithCoder:(NSCoder )解码器方法,就像NSCoding协议一样:

// Header @interface AnObject: NSObject <NSCoding> // Implementation - (void) encodeWithCoder:(NSCoder *)encoder { [encoder encodeObject:ivar1 forKey:@"ivar1"]; [encoder encodeFloat:ivar2 forKey:@"ivar2"]; } - (id)initWithCoder:(NSCoder *)decoder { self = [super initWithCoder:coder]; ivar1 = [[coder decodeObjectForKey:@"ivar1"] retain]; ivar2 = [[coder decodeObjectForKey:@"ivar2"] retain]; return self; } 

您也可以在这里查看官方文档。

在实现encodeWithCoder:initWithCoder:这里的自定义类是如何编写和读取的:

写:

 NSError *error; NSData* archiveData = [NSKeyedArchiver archivedDataWithRootObject:yourClassInstance]; [archiveData writeToFile:filePath options:NSDataWritingAtomic error:&error]; 

读:

 NSData *archiveData = [NSData dataWithContentsOfFile:filePath]; YourClass *yourClassInstance = (NSArray*)[NSKeyedUnarchiver unarchiveObjectWithData:archiveData]; 

使您的XYZ类符合NSCoding协议确实非常适合您要做的事情。 为此,请将NSCoding协议添加到您的类的接口声明中:

 @interface XYZ <NSCoding> 

然后,您需要在您的实现中实现encodeWithCoder:和initWithCoder:。 “编码器编码”意思是“把你的对象的当前状态,并把它打包成一个通用的对象,称为”编码器“。 “使用编码器初始化”意味着“给定一个已经包装的编码器对象,configuration自己的数据打包到编码器”。 在这两种方法中,“编码器”将是NSCoder的一个实例,它具有用于编码(“打包”)和解码(“解包”)基本types的非常简单的接口。

以下是一个示例实现:

 @implementation XYZ - (id)initWithCoder:(NSCoder*)encoder { self = [self init]; if (self) { self.myIntProperty = [encoder decodeIntForKey:@"myInt"]; } return self; } – (void)encodeWithCoder:(NSCoder*)decoder { [decoder encodeInt:self.myIntProperty forKey:@"myInt"]; } @end 

你需要实现两个方法: -encodeWithCoder:-encodeWithCoder: 阅读NSCoding文档; 他们是非常简单的方法。 您基本上想要用与其名称相对应的键对您的实例variables进行编码/解码。

这非常简单。 对于给定的class级Foo

 #import <Foundation/Foundation.h> @interface Foo : NSObject <NSCoding> { NSArray* bar_; NSUInteger baz_; } @property (nonatomic, retain) NSArray *bar; @property (nonatomic, assign) NSUInteger baz; @end 

为了符合NSCoding协议,你需要做的就是实现initWithCoder:decodeWithCoder消息:

 #import "Foo.h" @implementation Foo @synthesize bar = bar_; @synthesize baz = baz_; #pragma mark - NSCoding - (void)encodeWithCoder:(NSCoder *)encoder { [encoder encodeObject:self.bar forKey:@"bar"]; [encoder encodeInteger:self.baz forKey:@"baz"]; } - (id)initWithCoder:(NSCoder *)decoder { if ((self = [super init])) { self.bar = [decoder decodeObjectForKey:@"bar"]; self.baz = [decoder decodeIntegerForKey:@"baz"]; } return self; } - (void) dealloc { [bar_ release]; [super dealloc]; } @end