Сохранить NSMutableArray на диск - PullRequest
7 голосов
/ 04 мая 2009

У меня есть NSMutableArray, который содержит объекты типа Person (NSString, NSString, int) Я ищу простой способ сохранить этот массив на диск и загрузить его позже.

Я много читал о сериализации, но никогда не делал этого. Может быть, это не самый простой способ для меня.

Ответы [ 3 ]

10 голосов
/ 04 мая 2009

Первый шаг - заставить ваш класс 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, если вы хотите быть более ясным о том, как это делается. В обоих случаях вы также можете поместить свой массив в другую структуру данных (например, в словарь), если хотите включить другие элементы (например, номер формата файла) в файл данных.

4 голосов
/ 04 мая 2009

г. У Шарбонно правильная идея. 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 напрямую.)

1 голос
/ 14 июля 2011

Это не будет работать здесь, в моем коде с использованием 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: работает нормально.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...