2

我有一个从 NSObject 继承的名为 XYZ 的类和一个包含 XYZ 对象的数组。我需要将此数组写入到文档目录的 plist 文件中。尝试 [array writeToFile....] 后,我发现 writeToFile 失败,因为该数组包含 XYZ 类的自定义对象。

可能的解决方案是将对象转换为 NSData。实现这一目标的不同方法是什么?我发现NSCoding是合适的,但无法理解如何使用它。任何帮助将不胜感激。

4

5 回答 5

9

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

只需在对象中实现 *-(void)encodeWithCoder:(NSCoder )encode和 *-(id)initWithCoder:(NSCoder )decoder方法,这些方法尊重 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;
}

您也可以在此处查看官方文档。

于 2011-11-13T13:58:05.480 回答
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];
于 2011-11-13T14:00:45.047 回答
1

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

@interface XYZ <NSCoding>

然后,您需要在您的实现中实现 encodeWithCoder: 和 initWithCoder:。“使用编码器编码”意味着“获取对象的当前状态,并将其打包到一个称为“编码器”的通用对象中”。“Init with coder”的意思是“给定一个已经打包好的编码器对象,用打包到编码器中的数据来配置自己”。在这两种方法中,“编码器”都是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
于 2011-11-13T14:07:38.210 回答
0

您需要实现两种方法:-initWithCoder:-encodeWithCoder:. 阅读NSCoding文档;它们是非常直接的方法。您基本上想使用与其名称对应的键对实例变量进行编码/解码。

于 2011-11-13T13:55:57.743 回答
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:anddecodeWithCoder消息:

#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
于 2011-11-13T13:58:39.370 回答