2012-05-04 9 views
7

tengo esta matriz mutable llamado myWallet con su declaración de propiedad:Guardar un NSMutableArray utilizando NSUserDefaults no trabajar

@property (nonatomic, strong) NSMutableArray *myWallet; 

Esta matriz está siendo llenado por las tarjetas, que es un objeto. Creo una nueva instancia de una tarjeta de otro controlador de vista, así que utilizo un método de delegado para poder pasar esta tarjeta creada en mi controlador de vista inicial, que es un controlador de vista de tabla. A continuación se muestra el método delegado

- (void)addCardViewController:(AddCardViewController *)sender didCreateCard:(Card *)newCard 
{ 
    // insert a new card 

    self.myCard = newCard; 
    [self.myWallet addObject:self.myCard]; 

    [self.tableView reloadData]; 
} 

Hasta ahora, puedo crear nuevas instancias de la tarjeta, y cuando lo haga, una nueva celda de la tabla aparece en mi vista controlador (VC carpeta de la tarjeta) inicial.

Lo que quiero es que cuando el usuario termine de usar la aplicación, la (s) instancia (s) creada (s) de la Tarjeta que creó previamente todavía aparezcan en el siguiente tiempo de ejecución de la aplicación. Así que utilicé NSUserDefaults para hacer esto. El siguiente método es cómo estoy usando NSUserDefaults para guardar.

- (void)saveMyWallet 
{ 

    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; 

    [defaults setObject:self.myWallet forKey:@"myWalletArray"]; 

    [defaults synchronize]; 
    NSLog(@"I am saved"); 
} 

me llama a este método dentro de la didSelectRowAtIndexPath. Cuando ejecuto la aplicación, luego creo una nueva instancia de una Tarjeta, hago clic en la celda de la tabla, esto aparece en mi registro.

2012-05-04 14:51:00.900 CardWallet[24998:f803] *** -[NSUserDefaults setObject:forKey:]: Attempt to insert non-property value '("<Card: 0x6aa02f0>")' of class '__NSArrayM'. 
Note that dictionaries and arrays in property lists must also contain only property values. 

¿Cuál podría ser una posible razón para esto? Y puedes sugerirme formas en que puedo hacerlo.

Gracias de antemano.

+0

Primero quite la propiedad de su matriz y luego verifique qué valores tienen en su matriz usando nslog que va para la clave – vishiphone

Respuesta

4

Su clase de tarjeta también debe ajustarse a la NSCoding Protocol porque sólo se puede almacenar NSData, NSString, NSArray, NSDictionary y NSNumber con NSUserDefaults. Eso significa, es necesario agregar dos métodos a su clase:

- (void)encodeWithCoder:(NSCoder *)enCoder { 
    [super encodeWithCoder:enCoder]; 

    [enCoder encodeObject:instanceVariable forKey:INSTANCEVARIABLE_KEY]; 

    // Similarly for the other instance variables. 
    .... 
} 

- (id)initWithCoder:(NSCoder *)aDecoder { 

    if(self = [super initWithCoder:aDecoder]) { 
     self.instanceVariable = [aDecoder decodeObjectForKey:INSTANCEVARIABLE_KEY]; 

     // similarly for other instance variables 
     .... 
    } 

    return self; 
} 

continuación, crear un NSData NSKeyedArchiver antes de almacenarlo a NSUserDefaults. De esta manera:

NSUserDefaults *ud = [NSUserDefaults standardUserDefaults]; 
NSData *yourArrayAsData = [NSKeyedArchiver archivedDataWithRootObject:yourArray]; 
[ud setObject:sharesAsData forKey:kA_KEY_FOR_USERDEFAULTS]; 
+1

Eso no es suficiente, NSUserDefaults no los codificará automáticamente. ¡Tienes que hacerlo tú mismo! – ssteinberg

+1

Su derecho, ... actualicé mi respuesta –

+0

bien, voy a probar este – Grauzten

0

Si la matriz self.myWallet contiene objetos que no son objetos de lista de propiedades tendrá que codificar por sí mismo a NSData antes de guardar, y decodificar durante la carga.

Consulte la respuesta a esa question.

+0

¡Gracias! He pasado por esta misma respuesta, lo he intentado y todavía existe un error que ocurre durante el tiempo de ejecución. Probaré con la otra sugerencia anterior, donde también comentaste :) – Grauzten

4
@implementation Card 

- (void)encodeWithCoder:(NSCoder *)enCoder 
{ 
    [super encodeWithCoder:enCoder]; 
    [enCoder encodeObject:self.name forKey:@"CardName"]; 
    [enCoder encodeInt:self.pin forKey:@"CardPin"]; 
    [enCoder encodeDouble:self.points forKey:@"CardPoints"]; 
} 

- (id)initWithCoder:(NSCoder *)aDecoder 
{ 
    if(self = [super initWithCoder:aDecoder]) 
    { 
     self.name = [aDecoder decodeObjectForKey:@"CardName"]; 
     self.pin = [aDecoder decodeIntForKey:@"CardPin"]; 
     self.points = [aDecoder decodeDoubleForKey:@"CardPoints"];  
    } 
    return self; 
} 

@end 

supone que el nombre es de tipo NSString, el pasador es de tipo NSInteger y puntos es de tipo double se puede utilizar por encima de código directamente en su proyecto.

Cuestiones relacionadas