代码之家  ›  专栏  ›  技术社区  ›  TalkingCode

将nsmutableArray保存到磁盘

  •  7
  • TalkingCode  · 技术社区  · 15 年前

    我有一个nsmutableArray,它保存类型为person(nsstring、nsstring、int)的对象。 我正在寻找一种简单的方法将这个阵列保存到光盘上,稍后再加载它。

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

    3 回复  |  直到 13 年前
        1
  •  10
  •   Marc Charbonneau    15 年前

    第一步是让您的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: 方法,或者如果您想更明确地了解它是如何完成的,可以使用nskeedunachiver类。在这两种情况下,如果希望在数据文件中包含其他项(如文件格式编号),也可以将数组放入其他数据结构(例如字典)。

        2
  •  4
  •   Jeremy W. Sherman    15 年前

    查波诺先生有正确的想法。安 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 S,你可以自己把人变成他们 plistRepresentation 然后使用 -[NSArray writeToURL:atomically:] . (当然,你也可以使用 NSProperyListSerialization 直接。)

        3
  •  1
  •   user708586    13 年前

    在我的代码中,使用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

    #import <Foundation/Foundation.h>
    
    
    @interface MyClass : NSObject <NSCoding>
    {
    
    }
    
    @property (nonatomic,copy) NSString * foo;
    @property (nonatomic)      double  bar;
    
    
    @end
    

    MyClass

    #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:工作正常。