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

时间:2011-11-13 13:47:52

标签: iphone objective-c ios cocoa-touch nsdocumentdirectory

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

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

5 个答案:

答案 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