2012-09-28 36 views
0

最常見的做法在IOS setter方法如下:保留在iOS的setter方法釋放慣例

- (void)setMyString:(NSString *)newString { 
    if (newString != myString) { 
     [myString release]; 
     myString = [newString retain]; 
    } 
} 

相反,這不是很好的做法

- (void)setMyString:(NSString *)newString { 
    if (myString != nil) [myString release]; 
     myString = [newString retain]; 
    } 
} 

的原因是什麼平等檢查在第一種情況下?秒情況下的問題是什麼?

+0

@Till不是真的。請參閱下面的答案。 – 2012-09-28 14:28:24

+0

只是很好,爲什麼不使用常規的iOS屬性?你爲什麼需要setter –

+0

雖然你應該改變你的句子的順序,但是字符串屬性通常被聲明爲'copy'' not'retain' –

回答

0

我知道這是有些多餘,但...

如果新老對象是相同的,那麼你發送release到舊的對象和它得到釋放,指針到新對象將成爲懸掛指針作爲它指向的對象將不再存在(因爲它指向與舊對象指針相同的對象)。防爆。如果myStringnewString指向保留計數爲1的同一個實例,那麼您減去1,它將等於零。現在添加一個已經太晚了,因爲它會被釋放。但是,請撥打retainrelease,這應該沒問題。如果保留計數爲1,並且您添加一個,則現在是兩個,您可以安全地發送發佈。總的來說,在你斷言一個對象之前,我會說,首先聲明新對象的所有權。

此外,第一種類型的setter將是您將用於retain/strong樣式設置器。如果它是assign,則不需要保留/釋放,因爲不應該聲明所有權。 NSString通常有一個copy樣式設置器,它複製參數並使用它,這將創建一個副本而不是保留。我通常會使用copy來處理任何帶有可變子類的東西,因爲您不希望有人在NSMutableString中傳遞並將它在背後突變。 This page進入訪問器,並且您會注意到它們在釋放舊值之前保留了新值,並解釋原因。

2

如果你設置這樣的東西[object setMyString:[object myString]];沒有檢查相等 - 它會崩潰!因爲它會在你發送消息之前被釋放。 (如果只有對象自己的字符串)。同樣在第一個例子中,我們檢查平等以避免額外的操作。

+1

+1 - 所有權的問題比簡單地避免額外的setter調用要重要得多。 – 2012-09-28 14:28:00

+0

@ user1090590那麼規則是什麼?首先保留和釋放? – cateof

+0

我不認爲有一個「規則」。大多數人似乎都像你的第一個例子那樣做。無論如何,你是否考慮過使用ARC? – DrummerB