2009-08-20 9 views
6

プロパティにアクセスして変更したときにコードを起動したい。私は私のivarsのために私のコードで@property@synthesizeを使用します。プロパティは保持されているので、私はそのメモリ管理項目を自動的に@synthesizeによって生成しておきたいと思います。@synthesizeを使用する際にアクセサメソッドのカスタムカスタム実装を提供する方法はありますか?

しかし、私は@synthesizeがコードの右側にある@synthesize isのほとんどの場合、アクセサメソッドのコードを生成するようにコンパイラに指示すると仮定します。

私がプロパティfooを持っているとき、私は-setFoo-fooの方法を得ます。プロパティーが変更されたときにカスタムコードを実行するために、このようなメソッドを作成できますか?

-(void)setFoo { 
    // custom stuff 
} 

これは問題です。どのように最初のものを実行する?私はここで別の名前を持つことを嫌うだろう。 @synthesizeディレクティブでgetterメソッドとsetterメソッドの他の名前を作成できるようにする方法がありますか?そして、私はまだそれにアクセスするためにドット構文を使用することができるでしょうか?

答えて

5

普段と同じように@property@synthesizeを使用できますが、カスタムセッターまたはゲッター(またはその両方)を指定すると代わりに使用されます。通常、私は次のようなことをします:

// Override the setter 
- (void)setName:(NSString *)aName 
{ 
    if (name == aName) 
     return; 

    [name release]; 
    name = [aName retain]; 

    //custom code here 
} 

私はsetプロパティを使うと、私のカスタムメソッドが呼び出されます。ただし、getは合成されます。

+1

FYI、あなたのサンプルセッターにはバグがあります。同じオブジェクトで2回呼び出すと、そのオブジェクトが保持される前にそのオブジェクトが解放される可能性があります。本当に大きな問題ではありませんが、これらのことを正確に正しく行うことがいかに難しいかを示しています。 –

+0

私はそれに従うかどうかわかりません。代わりにどのように書かれているかを説明することができますか(それは私があなたを信じていないというわけではありません。ありがとう:) – jbrennan

+1

ああ、nvm私は問題を参照して、私は変更を反映するためにそれを更新します。 – jbrennan

1

setterまたはgetterの実装を提供する場合は、生成された実装の代わりにその設定が使用されます。コンパイル時にコンパイラによって生成されるgetterとsetterの「保持」の側面を実装するのは難しくありません。したがって、自分でgetterとsetterを書くだけで、そのことを言います。

-2

はい、@property宣言では、getterメソッドとsetterメソッドを指定できます。あなたのfoosetFoo:方法で

@property (readwrite,getter=privateGetFoo,setter=privateSetFoo:) NSObject * foo; 

、カスタムコード、その後[self privateGetFoo][self privateSetFoo:f]を呼び出します。

オブジェクトは、オブザーバ自体をaddObserver:forKeyPath:options:context:に設定することもできます。

私は、これらのどちらも非常にクリーンな方法ではないと言いました。他の人が示唆しているように、独自のゲッター/セッターを書く方が良いでしょう。

+0

あなたは言った: "あなたのfooとsetFoo:メソッド..." [obj setFoo:x]と[obj foo]は利用可能ですが、変更されたプロパティのためobj.fooは書くことができますし、obj.setFoo = xを使う必要があります。これは@propertyが通常行う方法ではありません。obj.fooは読み書きの両方に使用されます。 – mahboudz

+0

それから、object.fooは[object privateFoo]と同等です。これは、プロパティの使用目的をすべて破ります。 –

0

通常のプロパティの合成を行う抽象スーパークラスを作成するのは不吉な解決策です。 次に、実際に使用する具体的なサブクラスを作成し、メソッド(同じシグネチャ)を実装してオーバーライドし、実際の設定を行うためにsuperを呼び出します。 これにより、superの実装の呼び出しの前または後に何をしたいかを行うことができます。

例:

@interface ALTOClassA : NSObject 


@property NSString *catName; 

@end 

このテストのためのスタブファイルを超えて.Mに必要な何もありません。

、私たちは私たちのオーバーライドを行う@implementationで

#import "ALTOClassA.h" 

@interface ALTOClassAJunior : ALTOClassA 

@end 

@interfaceに特別に必要なものをサブクラスを作成していません。使用の際に

#import "ALTOClassAJunior.h" 

@implementation ALTOClassAJunior 


- (void)setCatName:(NSString*)aCatName { 
    NSLog(@"%@",NSStringFromSelector(_cmd)); 
    [super setCatName:aCatName]; 
    NSLog(@"after super: self.catName %@", self.catName); 
} 
@end 

ALTOClassAJunior *aCAJ = [ALTOClassAJunior new]; 
NSLog(@"aCAS.catName %@", aCAJ.catName); 

NSLog(@"set it to George."); 

[aCAJ setCatName:@"George"]; 

NSLog(@"aCAS.catName %@", aCAJ.catName); 

これは、あなたが自動生成されたコードを活用することができ、そしてまだあなたがあなたのクラスにしたいと思うものを行います。抽象スーパークラスは、多くの場合、しばしば便利なソリューションです。

関連する問題