将NSMutableArray保存到磁盘

时间:2009-05-04 11:06:28

标签: objective-c arrays serialization

我有一个NSMutableArray,它包含Person类型的对象(NSString,NSString,int) 我正在寻找一种简单的方法将此阵列保存到光盘并稍后再次加载。

我读了很多关于序列化但我从来没有这样做过。也许这对我来说不是最简单的方式。

3 个答案:

答案 0 :(得分:10)

第一步是让Person类实现NSCoding协议。基本策略是实现两个方法来序列化和取消序列化您希望在会话之间保留的每个对象的实例变量。

#pragma mark NSCoding Protocol

- (void)encodeWithCoder:(NSCoder *)encoder;
{
    [encoder encodeObject:[self foo] forKey:@"foo"];
    [encoder encodeDouble:[self bar] forKey:@"bar"];
}

- (id)initWithCoder:(NSCoder *)decoder;
{
    if ( ![super init] )
        return nil;

    [self setFoo:[decoder decodeObjectForKey:@"foo"]];
    [self setBar:[decoder decodeDoubleForKey:@"bar"]];

    return self;
}

要将对象实际写入磁盘,您可以使用NSArray的writeToFile:方法,或者如果您想更清楚地了解它是如何完成的,请使用NSKeyedUnarchiver类。在这两种情况下,如果要在数据文件中包含其他项(例如文件格式编号),也可以将数组放入另一个数据结构(例如字典)。

答案 1 :(得分:4)

先生。 Charbonneau有正确的想法。 NSCoder抽象对象的特定序列化,让您只关心需要序列化/反序列化的内容。在-encodeWithCoder:中,您可能想要

NSAssert1([encoder allowsKeyedCoding],
          @"%@ does not support sequential archiving.",
          [self className]);  

并非所有编码员都支持密钥存档。

-initWithCoder中,您应该在初始化对象之前向-initWithCoder:发送-init - 而不仅仅是super

self = [super initWithCoder:decoder];
if (!self) return nil;
// now use the coder to initialize your state

或者,由于您的对象基本上是属性列表,因此您可以添加-[Person plistRepresentation]之类的内容:

- (NSDictionary *)plistRepresentation
{
    return [NSDictionary dictionaryWithObjectsAndKeys:
            [self firstName], @"firstName",
            [self lastName], @"lastName",
            [NSNumber numberWithInteger:[self age]], @"age", nil];
}

然后,要序列化Person的数组,您可以自己将这些人转换为plistRepresentation,然后使用-[NSArray writeToURL:atomically:]。 (您当然也可以直接使用NSProperyListSerialization的方法。)

答案 2 :(得分:1)

通过使用writeToFile:atomically:

,它在我的代码中不起作用
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory , NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *issueURLsPlist = [documentsDirectory stringByAppendingPathComponent:@"test.plist"];

MyClass * myObject = [[MyClass alloc] init];
NSMutableArray * array = [[NSMutableArray alloc] init];
[array addObject:myObject];
[array writeToFile:issueURLsPlist atomically:YES];

MyClass.h

#import <Foundation/Foundation.h>


@interface MyClass : NSObject <NSCoding>
{

}

@property (nonatomic,copy) NSString * foo;
@property (nonatomic)      double  bar;


@end

MyClass.m

#import "MyClass.h"


@implementation MyClass

- (id)init {
self = [super init];
if (self) {
    self.foo = @"test";
    self.bar = 0.4f;
}
return self;
}

#pragma mark NSCoding Protocol

- (void)encodeWithCoder:(NSCoder *)encoder;
{
[encoder encodeObject:[self foo] forKey:@"foo"];
[encoder encodeDouble:[self bar] forKey:@"bar"];
}

- (id)initWithCoder:(NSCoder *)decoder;
{
if ( ![super init] )
    return nil;

[self setFoo:[decoder decodeObjectForKey:@"foo"]];
[self setBar:[decoder decodeDoubleForKey:@"bar"]];

return self;
}

@synthesize foo;
@synthesize bar;
@end

当我使用带有NSStrings的数组时,方法writeToFile:atomically:工作正常。