2009-05-04 21 views
7

Tengo un NSMutableArray que contiene objetos del tipo Persona (NSString, NSString, int) Estoy buscando una manera fácil de guardar esta matriz en el disco y volver a cargarla más tarde.Guardar NSMutableArray en el disco

He leído mucho sobre la serialización, pero nunca lo he hecho. Tal vez no es la forma más fácil para mí después de todo.

Respuesta

10

El primer paso es hacer que su clase Person implemente el protocolo NSCoding. La estrategia básica es implementar dos métodos para serializar y no serializar cada una de las variables de instancia del objeto que desea persistir entre sesiones.

#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; 
} 

escribir realmente los objetos en el disco, se puede utilizar el método de NSArray writeToFile:, o utilizar la clase NSKeyedUnarchiver si desea ser más explícito acerca de cómo se hace. En ambos casos, también puede colocar su matriz en otra estructura de datos (un diccionario, por ejemplo) si desea incluir otros elementos (como un número de formato de archivo) en su archivo de datos.

+0

eliminar de;; –

+1

en realidad supongo que no es necesario, se ve raro jaja –

4

El Sr. Charbonneau tiene la idea correcta. Un NSCoder abstrae la serialización específica de su objeto y le permite preocuparse solo por lo que necesita ser serializado/deserializado. En -encodeWithCoder:, es posible que desee

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

ya que no todos los codificadores apoyar archivado con llave.

En -initWithCoder, que debería estar enviando -initWithCoder: - no simplemente -init - a super antes de inicializar el objeto:

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

alternativa, ya que su objeto es básicamente una lista de propiedades ya, se puede añadir algo como -[Person plistRepresentation] :

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

Entonces, para serializar una serie de Person s, se puede transformar a sí mismo en las personas su plistRepresentation y luego use -[NSArray writeToURL:atomically:]. (Por supuesto, puede también emplear los métodos de NSProperyListSerialization directamente.)

1

no lo puedo trabajar aquí en mi código utilizando WriteToFile: atómicamente:

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 

MiClase. 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 

Cuando estoy usando una matriz con NSStrings entonces el método writeToFile: atomic aliado: está funcionando bien.

Cuestiones relacionadas