2009-05-18 25 views
5

die folgende Definition einer Klasse mit behalten Eigenschaften Gegeben: Warum nicht die synthetisierte "Warum benötigt diese Eigenschaft die "behalten"?

-(id)initWithCoder:(NSCoder*)coder 
{ 
    url = [[coder decodeObjectForKey:@"url"] retain]; 
    source = [coder decodeObjectForKey:@"source"]; 

    NSLog(@"got url=%@\n", url); 
    return self; 
} 

Im Einzelnen:

@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"]; 
} 

Warum hat die Eigenschaft url in initWithCoder Methode müssen die„behalten“ get url "Methode das Objekt behalten? (Ich vermute, die Source-Eigenschaft wird auch einen Retain benötigen).

Antwort

16

Schnell Antwort:

Wenn Sie ein:

url = [[coder decodeObjectForKey:@"url"] retain]; 

Sie sind nicht die @property verwenden. Sie legen den Wert der Instanzvariablen url manuell fest. Sie müssen daher auch manuell den Wert retain eingeben.

die Variable einzustellen, die synthetisierten Eigenschaften verwenden, würden Sie stattdessen rufen:

[self setUrl:[coder decodeObjectForKey:@"url"]]; 

oder

self.url = [coder decodeObjectForKey:@"url"]; 

Jede dieser Formen Verwendung der synthetisierten Methoden machen würde, und behandeln die retain automatisch .

Details:

In Objective-C, die @property und @synthesize Schlüsselwörter die Getter und Setter-Methoden für Sie automatisch erstellen:

@interface MyClass 
{ 
    id someValue; 
} 
@property (retain) id someValue; 
@end 

@implementation MyClass 
@synthesize someValue; 
@end 

entspricht:

@interface MyClass 
{ 
    id someValue; 
} 
- (id)someValue; 
- (void)setSomeValue:(id)newValue; 
@end 

@implementation MyClass 
- (id)someValue { return someValue; } 
- (void)setSomeValue:(id)newValue 
{ 
    [newValue retain]; 
    [someValue release]; 
    someValue = newValue; 
} 
@end 

Dies schafft einen wichtigen Unterschied zwischen der "internen" Mitgliedsvariablen und der Eigentum mit dem gleichen Namen. Wenn Sie die Elementvariable nach Name referenzieren, umgehen Sie die Methoden der synthetisierten Eigenschaft.

+0

In der Tat! Ich habe das Gefühl, dass mich das ziemlich oft beißen wird. Danke für deine Antwort. – Justicle

+0

Mein Vergnügen. Es ist zunächst etwas gewöhnungsbedürftig. Sobald Sie es für eine Weile getan haben, wird es zur zweiten Natur :) –

+4

Das ist einer der Gründe, warum ich ein _ Präfix für private Instanzvariablen verwende, es macht es sehr einfach zu sagen, wenn Sie eine Instanzvariable verwenden gegen alles andere. –

Verwandte Themen