以下代碼有任何問題?在Objective C中的dealloc中使用setter?
- (void) dealloc {
self.foo = nil;
}
而不是
- (void) dealloc {
[_foo release];
_foo = nil;
}
以下代碼有任何問題?在Objective C中的dealloc中使用setter?
- (void) dealloc {
self.foo = nil;
}
而不是
- (void) dealloc {
[_foo release];
_foo = nil;
}
有兩個原因不能前:
如果子類重寫了二傳手,釋放可能不會實際發生。
使用setter可能會觸發KVO通知,觀察者將收到來自技術上不存在的對象的通知。
另一方面,如果您使用ARC,則不需要執行任何操作。
沒有問題,如果你宣佈你的foo
財產與retain
或copy
屬性 但如果你使用assign
做到了,你不應該這樣做[_foo release];
您可能會發現這閱讀有用: Objective-C Memory Management for the Lazy
不鼓勵它的原因是它可能會導致問題。 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
}
這是一個簡單的例子,有可能發生更多的破壞性事情。
這裏的主要問題是,這兩者並不相同,因爲他們做了不同的事情。
請注意,如果您直接調用`release`並且不應調用某些應該調用的內容,則會發生同樣的問題。這取決於你如何編寫制定者。在你的例子中,你的二傳手設計不好。 – Sulthan 2011-12-15 18:16:11
我會寫兩個例子:
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];
}
正如你可以看到,這裏出現另一個錯誤。我們正在使用nil
(self.observer
)某處nil
可能不是預期的地方。
一般來說,這兩種情況都不會幫助您發現錯誤。在任何情況下,都會出現不同類型的小車行爲。
我的建議是使用setter來保持一致性,但這是一個意見問題。 無論如何,如果你編寫你自己的setter,檢查你是否正在以正確的順序初始化和取消分配屬性。還要注意你的setter可以在子類中被覆蓋。
蘋果建議直接使用在init和dealloc的,但在自己的代碼,他們使用的制定者保留/釋放(例如UITableView
重新分配時有nil
參數調用setDelegate
)。
請注意......如果你不使用ARC,你需要調用`[super dealloc]`,如果你是那麼你不應該調用`release`。 – 2011-12-15 15:22:04