2011-12-15 54 views
0

以下代碼有任何問題?在Objective C中的dealloc中使用setter?

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

而不是

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

請注意......如果你不使用ARC,你需要調用`[super dealloc]`,如果你是那麼你不應該調用`release`。 – 2011-12-15 15:22:04

回答

3

有兩個原因不能前:

  1. 如果子類重寫了二傳手,釋放可能不會實際發生。

  2. 使用setter可能會觸發KVO通知,觀察者將收到來自技術上不存在的對象的通知。

另一方面,如果您使用ARC,則不需要執行任何操作。

2

不鼓勵它的原因是它可能會導致問題。 setter或getter可能有副作用

以內存泄漏爲例。

- (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 
} 

這是一個簡單的例子,有可能發生更多的破壞性事情。

這裏的主要問題是,這兩者並不相同,因爲他們做了不同的事情。

+0

請注意,如果您直接調用`release`並且不應調用某些應該調用的內容,則會發生同樣的問題。這取決於你如何編寫制定者。在你的例子中,你的二傳手設計不好。 – Sulthan 2011-12-15 18:16:11

1

我會寫兩個例子:

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_觀察者不會被移除,這可能是一個錯誤。

2 /使用二傳手


- (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]; 
} 

正如你可以看到,這裏出現另一個錯誤。我們正在使用nilself.observer)某處nil可能不是預期的地方。

一般來說,這兩種情況都不會幫助您發現錯誤。在任何情況下,都會出現不同類型的小車行爲。

我的建議是使用setter來保持一致性,但這是一個意見問題。 無論如何,如果你編寫你自己的setter,檢查你是否正在以正確的順序初始化和取消分配屬性。還要注意你的setter可以在子類中被覆蓋。

蘋果建議直接使用在init和dealloc的,但在自己的代碼,他們使用的制定者保留/釋放(例如UITableView重新分配時有nil參數調用setDelegate)。