Given the following definition of a class with retain properties:
@interface FeedEntry : NSObject<NSCoding>
{
NSURL* url;
NSData* source;
}
@property (retain) NSURL* url;
@property (retain) NSData* source;
@end
@implementation FeedEntry
@synthesize url;
@synthesize source;
-(void)encodeWithCoder:(NSCoder*)coder
{
[coder encodeObject:url forKey:@"url"];
[coder encodeObject:source forKey:@"source"];
}
Why does the url property in initWithCoder method need the “retain”:
-(id)initWithCoder:(NSCoder*)coder
{
url = [[coder decodeObjectForKey:@"url"] retain];
source = [coder decodeObjectForKey:@"source"];
NSLog(@"got url=%@\n", url);
return self;
}
Specifically, why doesn’t the synthesized “get url” method retain the object? (I’m guessing the source property will need a retain as well).
Quick answer:
When you set:
you are not using the
@property. You are manually setting the value of the instance variableurl. You must, therefore, also manuallyretainthe value.To set the variable using the synthesized properties, you would instead call:
or
Either of these forms would make use of the synthesized methods, and handle the
retainautomatically.Details:
In Objective-C, the
@propertyand@synthesizekeywords automatically create the getter and setter methods for you:Is equivalent to:
This creates an important distinction between the “internal” member variable and the property having the same name. If you reference the member variable by name, you are bypassing the synthesized property methods.