2010-08-12 13 views
7

Mi problema es cuando recupero mi NSArray de objetos Store, todas mis propiedades NSString están causando errores BadAccess. ¡Las propiedades int y double funcionan bien!NSCoding con como NSString dentro de un objeto

store.h

@interface Store : NSObject<NSCoding> { 
    NSString *Name; 
    NSString *Address; 
    NSString *Phone; 
    double GeoLong; 
    double GeoLat; 
    int ID;   
} 

@property (nonatomic, retain) NSString *Name; 
@property (nonatomic, retain) NSString *Address; 
@property (nonatomic, retain) NSString *Phone; 
@property (nonatomic) double GeoLat; 
@property (nonatomic) double GeoLong; 
@property (nonatomic) int ID; 

@end 

store.m

@implementation Store 

@synthesize Name; 
@synthesize ID; 
@synthesize Address; 
@synthesize Phone; 
@synthesize GeoLat; 
@synthesize GeoLong; 


/** Implentation of the NSCoding protocol. */ 

-(void)encodeWithCoder:(NSCoder *)encoder 
{ 
    [encoder encodeInt:ID forKey:@"ID"]; 
    [encoder encodeDouble:GeoLat forKey:@"GeoLat"]; 
    [encoder encodeDouble:GeoLong forKey:@"GeoLong"]; 
    NSLog(@"Name in encode: %@", Name); //WORKS! 
    [encoder encodeObject:Name forKey:@"Name"]; 
    [encoder encodeObject:Phone forKey:@"Phone"]; 
    [encoder encodeObject:Address forKey:@"Address"]; 

} 

-(id)initWithCoder:(NSCoder *)decoder 
{ 
    // Init first. 
    if(self = [self init]){ 

    ID = [decoder decodeIntForKey:@"ID"]; 
    GeoLat = [decoder decodeDoubleForKey:@"GeoLat"]; 
    GeoLong = [decoder decodeDoubleForKey:@"GeoLong"]; 
    Name = [decoder decodeObjectForKey:@"Name"]; 
    NSLog(@"Name in decode: %@", Name); //WORKS! logs the name 

    Address = [decoder decodeObjectForKey:@"Address"]; 
    Phone = [decoder decodeObjectForKey:@"Phone"]; 
    } 

    return self; 
} 

- (void)dealloc 
{ 
    [Name release]; 
    [ID release]; 
    [Address release]; 
    [Phone release]; 


    [super dealloc]; 
} 
@end 

Aquí está mi código para almacenar y retriving la matriz.

//streams contains the data i will populate my array with. 
for (ndx = 0; ndx < streams.count; ndx++) { 
      NSDictionary *stream = (NSDictionary *)[streams objectAtIndex:ndx]; 

      Store *item = [[Store alloc] init] ; 
      item.Name = [stream valueForKey:@"Name"]; 
      item.Address = [stream valueForKey:@"Address"]; 
      item.Phone = [stream valueForKey:@"Phone"]; 
      item.GeoLat = [[stream valueForKey:@"GeoLat"] doubleValue]; 
      item.GeoLong = [[stream valueForKey:@"GeoLong"] doubleValue];     
      item.ID = [[stream valueForKey:@"ID"] intValue]; 

      [listToReturn addObject:item]; 
     } 
    } 

    //test to check if it works 
    for(int i = 0; i < [listToReturn count]; i++){ 
     Store *item = (Store *)[listToReturn objectAtIndex:i]; 
     NSLog(@"Name: %@", item.Name); //works 
    } 

    //save 
    [[NSUserDefaults standardUserDefaults] setObject:[NSKeyedArchiver archivedDataWithRootObject:listToReturn] forKey:@"stores"]; 

    // retrieve 
    NSMutableArray *stores = [NSMutableArray new]; 
    NSUserDefaults *currentDefaults = [NSUserDefaults standardUserDefaults]; 
    NSData *dataRepresentingSavedArray = [currentDefaults objectForKey:@"stores"]; 
    if (dataRepresentingSavedArray != nil) 
    { 
     NSArray *oldSavedArray = [NSKeyedUnarchiver unarchiveObjectWithData:dataRepresentingSavedArray]; 
     if (oldSavedArray != nil) 
      stores = [[NSMutableArray alloc] initWithArray:oldSavedArray]; 
     else 
      stores = [[NSMutableArray alloc] init]; 
    } 

    if ([stores count] > 0) { 
     NSMutableArray * annotations = [[NSMutableArray alloc] init]; 
     for(int i = 0;i< [stores count]; i++){ 

      Store *store = [stores objectAtIndex: i]; 

      CLLocationCoordinate2D location; 
      if(store.GeoLat != 0 && store.GeoLong != 0){ 
       location.latitude = store.GeoLat; 
       location.longitude = store.GeoLong; //works 
       NSLog(@"Adding store: %@", store.Name); //DONT WORK!! <-- MAIN PROBLEM 
      } 
     } 
    } 

Se siente como he intentado todo pero no puedo averiguar cómo funciona en la decodificación, pero no cuando en el bucle de la matriz después de que lo puso en una matriz.

¿Alguien tiene alguna idea?

+0

Hey, soy consciente de que no tiene que ver con la cuestión que nos ocupa, pero sólo para tu información. Los nombres de las variables iniciales con letras mayúsculas van en contra de todas las pautas de estilo. – DougW

+0

En Objective-c, los ivars deben tener letras mayúsculas en la primera letra y las clases deben tener mayúsculas en la primera letra ... solo una convención. – hfossli

Respuesta

12

No está conservando las propiedades en initWithCoder.

Name = [decoder decodeObjectForKey:@"Name"]; 

no está utilizando el colocador de la propiedad (retención) que ha definido. Solo estás configurando el ivar. Eso significa que usted no adquiere la propiedad y puede ser desasignado.

Aquí hay dos maneras en que puede retener las propiedades en su caso:

self.Name = [decoder decodeObjectForKey:@"Name"]; 
Name = [[decoder decodeObjectForKey:@"Name"] retain]; 
+0

increíble, SO rocas, y tú también :) –

+0

Buena y rica explicación :) era justo lo que también estaba buscando :) – chrs

Cuestiones relacionadas