2010-11-19 32 views
9

我確定我錯過了對iOS內存管理的一些基本理解,儘管有大量的閱讀和搜索,但我仍然沒有得到它。iOS單身人士和內存管理

我在我的應用程序中使用了一個包含當前用戶登錄信息,從多個視圖控制器訪問的信息等的單例。它具有多個在應用程序中獲取和設置的ivars。他們在聲明和.h文件有產者像這樣:

NSString *myString; 

和由保留像這樣:

@property (non atomic, retain) NSString *myString; 

,並在實施synththesized。

我得到和在單這樣的方法設置它們的值:

myString = @"value"; 

methodLocalString = myString; 

在其他地方,包括我的單身 - 稱之爲CurrentUser - 我導入它:

#import "CurrentUser.h"  

在我得到的單例之外,設置這樣的:

[CurrentUser sharedCurrentUser].myString = @"Bob"; 

myOutsideString = [CurrentUser sharedCurrentUser].myString; 

這其中大部分的偉大工程的時候,用值在一個獲取或設置到另一個適當的堅持。麻煩的是,有時當我以這種方式獲得它們時,我發現它們已經被釋放(崩潰應用程序),NSZombieEnabled謝天謝地告訴我。

我不明白的是他會如何發生。我認爲這個單身人士永遠不會被釋放,因此保留單身人士的屬性永遠不會被釋放。我會注意到,這個問題似乎更常見於像NSDate這樣的非真實對象屬性以及不能保留的int和BOOL等絕對非對象屬性,但它也發生在對象屬性中。

我對這裏一無所知?並感謝您的耐心。

+0

很好的問題。等待澄清。 – harshalb 2010-11-19 04:57:49

+1

不要在'NSString'屬性中使用'retain'。使用'copy'。 – 2010-11-19 08:32:51

+0

謝謝你的不在副本上。這應該是所有支持NSCopying的對象,對吧? – 2010-11-19 09:23:31

回答

14

您的問題是:

我得到和在單身這樣設置其值的方法 :

myString = @"value";

當您直接分配到伊娃,而不是使用屬性語法(self.myString = @"value"),您繞過了合成的setter方法,這意味着retain從不發生。

屬性並不神奇。他們只是一些「」的語法糖。「訪問以及合成getter/setter方法的能力,從而爲您節省編寫自己的繁瑣工作。

self.myString = @"value"; 

[self setMyString:@"value"]; 

合成setMyString方法會做這樣的事情只是速記:

if (myString != newValue) { 
    [myString release]; 
    myString = [newValue retain]; 
} 

(假設在@synthesize retain選項)

+0

這使*完美*感,謝謝! – 2010-11-19 05:14:22

0

Don't use singletons.您當前的問題是由...造成的簡單的記憶管理誤解,但單身模式只會讓你長期頭痛。

+1

感謝您的建議。我已閱讀了十多篇關於利弊的文章,並對我的選擇感到滿意。 – 2010-11-19 13:16:19

+2

一般而言,iOS應用程序中的單身人士最終會令您頭痛不已。但是,如果你小心,你可以使用它們。但是,你永遠不應該做的一件事就是引用你的單例中的UIKit元素。我已經在許多項目中評論過開發人員使用單例,並且基本上任何時候單身持有引用UIKit對象或引用UIKit對象的其他對象的引用時,您最終都會在腳下拍攝自己。內存泄漏工具不會像這樣捕獲UIKit泄漏,並且您將留下一堆難以修復的循環引用。 – MoDJ 2011-06-09 20:59:44