开发者

NSInteger and decodeInteger:forKey: Problems

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.frequenc开发者_开发百科y =   [[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:

self.idnum =       [[decoder decodeIntegerForKey:@"idnum"] retain];

That code is sending 'retain' to an NSInteger. NSIntegers aren't objects though, they're just scalars. That is illegal. Just use this instead:

self.idnum =       [decoder decodeIntegerForKey:@"idnum"];

Next, this code:

self.exercises =   [[decoder decodeObjectForKey:@"exercises"] retain];

Is over retaining, and will cause a leak. Since you declared exercises like:

@property(nonatomic,retain) NSMutableArray *exercises; 

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:

exercises =   [[decoder decodeObjectForKey:@"exercises"] retain];

Or:

self.exercises =   [decoder decodeObjectForKey:@"exercises"];


Is your project's deployment target set to Mac OS 10.5 or later? NSInteger was only introduced in Leopard so if you're targeting Tiger you will need to provide implementations of NSInteger and -decode/encodeIntegerForKey:

As an aside, generally you should avoid using accessors when setting ivars in init methods. You should normally just set the ivars directly.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜