2011-06-19 7 views
35

クラスAがあると:オーバーライド@propertyセッターと無限ループ

@interface ClassA : NSObject { 
} 
@property (nonatomic, assign) id prop1; 
@end 

@implementation 
@synthesize prop1; 
@end 

その後、私は、サブクラス

@interface ClassB : ClassA { 
} 
@end 

@implementation 

- (id)init { 
    self = [super init]; 
    if (self) { 
    } 
    return self; 
} 

//This is infinite loop 
- (void) setProp1:(id)aProp 
{ 
    self.prop1 = aProp; 
} 
@end 

を持っているとClassBのからsetProp1は[ClassBのsetProp1ます。val]呼び出すので、これは無限ループですクラスB内から。

私はすでに[スーパーsetProp1]通話を試みたが、@propertyを上書きし、上書きされたセッターの内側に値を割り当てるには、どのようにこの

ましたか? ClassAを変更できないとしましょう。

+0

"私はすでに[super setProp1]を呼び出してみましたが、これは..."なにが問題だったの? 'super'はここで正しいです。 –

+0

スーパーのスーパーチェンジ値のみ。 self.prop1はnullで、super.prop1は値を持ちます。self-> prop1(Shermが示唆するように) – Marcin

+1

self.prop1とsuper.prop1は間違いなく別の値を返すべきではありません。ゲッターメソッドもオーバーライドしていますか? –

答えて

54

だけでセッターを呼び出すために、ドットシンタックスを使用せずに、直接インスタンス変数に割り当てる:

- (void) setProp1:(id)aProp 
{ 
    self->prop1 = aProp; 
} 

種類のかかわらず、質問を頼むこと。このアクセサは、親がやろうとしていたこととまったく同じです。親をオーバーライドするのは何ですか?

@synthesize selectedQuestion = _selectedQuestion; 

そして_selectedQuestionとしてそれを参照してください。

+3

の例は単なる目的例です。 – Marcin

+2

GCC 4.2を使用しない限り、 'self->'部分は必要ありません。 – bbum

+3

真実ですが、AFAIKは問題ありません。アクセサーメソッドを経由せずにivarにアクセスしていることを少しでも見ていることを視覚的に通知します。 –

5

別の選択肢はそうのような別の名前に合成された変数を設定することです。これにより、self.selectedQuestionを意味するときにselectedQuestionを誤って記述することを防ぎます。

ただし、Appleはアンダースコアを使用することをお勧めします。別の名前を使うこともできますが、@ Shermの方法が一番です。

9

再帰呼び出しを作成するため、セッター内では「self」を使用しないでください。

また、同じオブジェクトを割り当てていないことを確認し、新しいオブジェクトを保持し、割り当て前に古いオブジェクトを解放する必要があります。

し、前述したとおりに、セッター名を再定義する必要があります

@synthesize prop1 = prop1_; 

... 

- (void) setProp1:(id)aProp 
{ 
    if (prop1_ != aProp) { 
     [aProp retain]; 
     [prop1_ release]; 
     prop1_ = aProp; 
    } 
} 
+0

これは 'retain'プロパティに対してのみ行うべきです、OPの例は' assign'プロパティです。 – pancake

+0

私を救った部分は**再帰呼び出しを作成するのでsetterの中で "self"を使うべきではありません** ** self。**をアンダースコアに置き換えると、魔法が起こりました。 – LargeGlasses

4

単に@synthesizeあなたのサブクラスでは、所望の特性、そしてあなたは、直接プロパティにアクセスするための名前としてそれを使用することができます

メイン・クラス・インタフェース:

@interface AClass : NSObject 

@property (nonatomic, assign) id<someProtocol> delegate; 

@end 

サブクラスインタフェース:

@interface BCLass : AClass 
@end 

サブクラス実装:XCodeのでは

@implementation BCLass 

@synthesize delegate = _delegate; 

- (void)setDelegate:(id<someProtocol>)d{ 
    _delegate = d; 
} 

@end 
21

4.5+とLLVM 4.1 @synthesizeする必要はありません、あなたはを参照する_prop1を取得します。

- (void) setProp1:(id)aProp 
{ 
    _prop1 = aProp; 
} 

うまく動作します。