NSCoding using NSString inside an object

My problem is that I am retrieving NSArray from Store objects, all my NSString properties are causing BadAccess errors. The int and double properties work fine!

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 

Here is my code for storing and retrieving an array.

 //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 } } } 

It looks like I tried everything, but I can’t understand how it works in decoding, but not in the loop of the array after I put it in the array.

Does anyone have any idea?

+7
objective-c iphone nsuserdefaults nscoding nskeyedarchiver
source share
1 answer

You do not save properties in initWithCoder .

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

does not use the installer of the (saving) property that you defined. You just install ivar. This means that you are not acquiring property and you can free it.

Here are two ways to save properties in your case:

 self.Name = [decoder decodeObjectForKey:@"Name"]; Name = [[decoder decodeObjectForKey:@"Name"] retain]; 
+12
source share

All Articles