我有一个名为XYZ的类,它继承自NSObject和一个包含XYZ对象的数组。我需要将此数组写入文档目录中的plist文件。在尝试[array writeToFile ....]后,我发现writeToFile失败,因为该数组包含XYZ类的自定义对象。
可能的解决方案是将对象转换为NSData。有什么不同的方法来实现这一目标?我发现 NSCoding 是合适的,但无法理解如何使用它。任何帮助将不胜感激。
答案 0 :(得分:9)
Ray Wenderlich's blog上有一个非常好的教程,解释了如何使用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;
}
您还可以查看官方文档here。
答案 1 :(得分:9)
在为自定义类实现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];
答案 2 :(得分:1)
将您的XYZ类符合NSCoding协议确实非常适合您要做的事情。为此,请将NSCoding协议添加到类的接口声明中:
@interface XYZ <NSCoding>
然后,您需要在您的实现中实现encodeWithCoder:和initWithCoder :. “用编码器编码”意味着“获取对象的当前状态,并将其打包成称为'编码器'的通用对象”。 “使用编码器初始化”意味着“给定已经打包的编码器对象,使用打包到编码器中的数据进行自我配置”。在这两种方法中,'encoder'将是NSCoder的一个实例,它具有一个相当简单的接口,用于编码(“打包”)和解码(“解包”)基本类型。
以下是一个示例实现:
@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
答案 3 :(得分:0)
您需要实现两种方法:-initWithCoder:
和-encodeWithCoder:
。阅读NSCoding
文档;他们是非常简单的方法。您基本上希望使用与其名称对应的键对您的实例变量进行编码/解码。
答案 4 :(得分:0)
这很直截了当。对于给定的班级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