我有以下两种归档方法:
- (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;
}
标题:
@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
看起来很简单。 encodeInteger接受一个NSInteger,我传递给它,而decodeIntegerForKey返回一个NSInteger,但我得到了这个奇怪的错误:
警告:无效的接收器类型'NSInteger'
当执行decodeIntegerForKey指令时,我得到一个exec错误访问。
为什么会这样?
答案 0 :(得分:8)
发布的代码存在一些问题。第一:
self.idnum = [[decoder decodeIntegerForKey:@"idnum"] retain];
该代码正在向NSInteger发送'retain'。虽然NSIntegers不是对象,但它们只是标量。这是非法的。只需使用它:
self.idnum = [decoder decodeIntegerForKey:@"idnum"];
接下来,这段代码:
self.exercises = [[decoder decodeObjectForKey:@"exercises"] retain];
过度保留,会导致泄漏。既然您宣布了以下练习:
@property(nonatomic,retain) NSMutableArray *exercises;
“保留”意味着当你调用setter时,它会保留传入的值,然后将其粘贴到“exercise”实例变量中。你在调用setter之前保留,所以这是一个双重保留。
您可以通过将代码更改为:
来解决此问题exercises = [[decoder decodeObjectForKey:@"exercises"] retain];
或者:
self.exercises = [decoder decodeObjectForKey:@"exercises"];
答案 1 :(得分:1)
您项目的部署目标是否设置为Mac OS 10.5或更高版本? NSInteger
仅在Leopard中引入,因此,如果您定位Tiger,则需要提供NSInteger
和-decode/encodeIntegerForKey:
的实现
顺便说一下,在init方法中设置ivars时通常应该避免使用访问器。您通常应该直接设置ivars。