I have the following two archiving methods:
- (void) encodeWithCoder: (NSCoder *) encoder {
[encoder encodeObject:self.exercises forKey:@"exercises"];
[encoder encodeObject:self.title forKey:@"title"];
[encoder encodeObject:self.description forKey:@"description"];
[encoder encodeInteger:self.idnum forKey:@"idnum"];
[encoder encodeInteger:self.rating forKey:@"rating"];
[encoder encodeInteger:self.frequency forKey:@"frequency"];
NSLog(@"Encoding!");
}
- (id) initWithCoder: (NSCoder *) decoder {
self.exercises = [[decoder decodeObjectForKey:@"exercises"] retain];
self.title = [[decoder decodeObjectForKey:@"title"] retain];
self.description = [[decoder decodeObjectForKey:@"description"] retain];
self.idnum = [[decoder decodeIntegerForKey:@"idnum"] retain];
self.rating = [[decoder decodeIntegerForKey:@"rating"] retain];
self.frequency = [[decoder decodeIntegerForKey:@"frequency"] retain];
NSLog(@"Decoding!");
return self;
}
And a header:
@interface Workout : NSObject{
NSMutableArray *exercises;
NSString *title;
NSString *description;
NSInteger idnum;
NSInteger rating;
NSInteger frequency;
}
- (void) encodeWithCoder: (NSCoder *) encoder;
- (id) initWithCoder: (NSCoder *) decoder;
@property(nonatomic,retain) NSMutableArray *exercises;
@property(nonatomic,retain) NSString *title;
@property(nonatomic,retain) NSString *description;
@property(nonatomic) NSInteger idnum;
@property(nonatomic) NSInteger rating;
@property(nonatomic) NSInteger frequency;
@end
It seems simple enough. encodeInteger takes an NSInteger, which I pass to it, and decodeIntegerForKey returns an NSInteger, but I get this weird errors:
warning: invalid receiver type ‘NSInteger’
and when the decodeIntegerForKey instruction is executed, I get an exec bad access.
Why is this happening?
There are a couple problems with the posted code. First:
That code is sending ‘retain’ to an NSInteger. NSIntegers aren’t objects though, they’re just scalars. That is illegal. Just use this instead:
Next, this code:
Is over retaining, and will cause a leak. Since you declared exercises like:
That “retain” means that when you call the setter, it will retain the passed in value before sticking it in the “exercises” instance variable. You’re retaining before calling the setter though, so that’s a double retain.
You could fix this by changing your code to either:
Or: