2009-05-18 2 views
5

は保持特性を持つクラスの次の定義を考える: このプロパティに「保持」が必要なのはなぜですか?

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

はなぜ「保持」initWithCoderメソッドでurlプロパティ必要がありません:

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

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

具体的には、理由を合成していません」 get url "メソッドはオブジェクトを保持しますか? (私はソースプロパティを推測しているので、保持する必要もあります)。

答えて

16

クイック答え:

が設定した:

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

あなたが@propertyを使用してないです。インスタンス変数urlの値を手動で設定しています。したがって、手動で値をretainにする必要があります。

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

または

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

これらの形態のいずれかの

が合成された方法の使用をするだろう、と自動的に retainを扱う:

が合成されたプロパティを使用して変数を設定するには、代わりに呼び出します。

詳細:

のObjective-C、@property@synthesizeキーワードが自動的にgetterメソッドとsetterメソッドを作成するには:

@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 

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

@implementation MyClass 
@synthesize someValue; 
@end 

に相当しますこれは、 "内部"メンバ変数と同じ名前のプロパティ。メンバー変数を名前で参照すると、合成プロパティメソッドをバイパスします。

+0

実際に!これは私をかなり頻繁に噛む気がします。お返事をありがとうございます。 – Justicle

+0

私の喜び。最初は慣れていました。一度それをやってしまえば、それは第二の性質になります:) –

+4

私はプライベートインスタンス変数に_プレフィックスを使用するのが好きです。それはインスタンス変数を使用しているときにわかりやすくなります他に何か? –

関連する問題