2011-12-15 6 views
0

次のコードに問題がありますか?Objective Cのdeallocでのsetterの使用?

- (void) dealloc { 
    self.foo = nil; 
} 

代わりの

- (void) dealloc { 
    [_foo release]; 
    _foo = nil; 
} 
+6

1つの注意点... ARCを使用していない場合は、[[super dealloc]]を呼び出す必要があります。そうであれば、 'release'を呼び出すべきではありません。 –

答えて

3

:サブクラスはセッターをオーバーライドしている場合

  1. は、リリースには、実際には起こらないかもしれません。

  2. setterを使用すると、KVO通知がトリガされ、オブザーバは、技術的に存在しないオブジェクトから通知を受け取ります。

一方、ARCを使用する場合は、その必要はありません。

1

問題ありませんあなたはretaincopy 属性が、あなたは[_foo release];

を行うべきではありませんassignを使用してそれをしなかった場合は、これを見つけるかもしれないとあなたのfooプロパティを宣言した場合便利な読み: Objective-C Memory Management for the Lazy

2

それが推奨されないのは、問題を引き起こす可能性があるからです。セッターまたはゲッターに副作用がある可能性があります。

メモリリークのこの例を考えてみましょう。

- (void)dealloc; 
{ 
    self.iWillLeak = nil; 
    self.iCauseTheLeak = nil; 
    [super dealloc]; 
} 

- (void)setICauseTheLeak:(NSArray *)iCauseTheLeak; 
{ 
    if (_iCauseTheLeak != iCauseTheLeak) { 
     [_iCauseTheLeak release]; 
     _iCauseTheLeak = [iCauseTheLeak retain]; 
    } 
    self.iWillLeak = [NSArray array]; // This was already cleared in dealloc 
} 

これは単純なケースであり、より多くの損害を与える可能性があります。

ここでの主なテイクアウトは、2つの機能が同じではないことです。旧を行うにはない二つの理由があります

+0

'release'を直接呼び出して呼び出されるものが呼び出されない場合、同じ問題が発生することに注意してください。それはあなたがセッターを書く方法に依存します。あなたの例では、セッターはうまく設計されていません。 – Sulthan

+0

setterは、deallocでsetter/getterを使用することをお勧めしない理由の例を示すために意図的に書かれています。 –

+0

あなたが示したのは、正しく書かれていないときにセッターを直接呼び出すべきではないということだけです。 – Sulthan

1

私は2つの例を記述します:

1 /を直接


- (void)dealloc { 
    [foo_ release]; 
    [super dealloc]; 
} 

- (void)setFoo:(Foo*)foo { 
    if (foo == foo_) { 
     return; 
    } 

    [foo_ removeObserver:self]; 
    [foo_ release]; 

    foo_ = [foo retain]; 
    [foo_ addObserver:self]; 
} 

のリリースを使用してfoo_からのオブザーバーは、おそらく誤りである、削除されません。セッター


- (void)dealloc { 
    self.observer = nil; 
    self.foo = nil; 
    [super dealloc]; 
} 

- (void)setFoo:(Foo*)foo { 
    if (foo == foo_) { 
     return; 
    } 

    [foo_ removeObserver:self.observer]; 
    [foo_ release]; 

    foo_ = [foo retain]; 
    [foo_ addObserver:self.observer]; 
} 

を使用して

2 /あなたが見ることができるように、別のエラーがここに表示されます。我々は、(self.observer)のどこかでnilがおそらく期待されていないところを使用しています。

一般に、この2つのケースのどちらも、あなたのバグを捕まえるのに役立ちません。どのような場合でも、さまざまな種類のバグが発生する可能性があります。

私のお勧めは、一貫性を維持するために設定者を使用することですが、それは意見の問題です。 とにかく、独自のセッターを書く場合は、プロパティを正しい順序で初期化しているかどうかを確認してください。また、セッターはサブクラスでオーバーライドできます。

アップルは、initとのdeallocで直接保持/解放を使用することをお勧めしますが、独自のコードでは、それらは(解放とき例えばUITableViewnilパラメータでsetDelegateを呼び出し)セッターを使用します。

関連する問題