2011-03-24 92 views
0

我一直有NSDate的一些問題,並將其保存在NSUserDefaults。它每隔兩秒就會關聯NSUserDefaults保存我的NSDate,但它不能,因爲它已被釋放,並在日誌中顯示此錯誤。NSDate保留消息發送到解除分配的實例

-[__NSDate retain]: message sent to deallocated instance 0x4c20c80 

我知道的NSDate allocs並以不同的方式,正常的對象deallocs,但我想知道是否有人知道,如果使用:

- (void)saveData 
{ 
NSUserDefaults *data = [NSUserDefaults standardUserDefaults]; 
[data setObject:dateOpened forKey:@"dateOpened"]; 
[dData synchronize]; 
} 

......或者......

- (void)loadData 
{ 
NSUserDefaults *data = [NSUserDefaults standardUserDefaults]; 
dateOpened = [data objectForKey:@"dateOpened"]; 
} 

我正在發佈我的NSDate實例,因此給它一個保留計數爲0,所以我的應用程序在它嘗試時不能保存它嗎?

我使用:

@property (retain) NSDate *dateOpened; 

任何想法的將是非常感激,因爲我要瘋了試圖找出了這一點。我只學了大約4個月左右的時間,幾乎完成了我的第一個應用程序,這是一個主要的作品!

非常感謝,如果您需要更多關於我在做什麼的代碼或信息,請告訴我。 :-D

+0

在您的示例代碼,你在哪裏保存和加載數據時,伊娃說CLOSED(dateClosed),關鍵說OPENED(dateOpened)。但是當你提到@property行時,你說這個ivar是dateOpened(OPENED)。你說你不是在混日子嗎? – 2011-03-24 23:36:02

+0

對不起,忘了改變它。剛剛編輯它如何它被認爲是。日期不會混淆,只是我的錯誤複製和粘貼。 :) – Baza207 2011-03-24 23:41:57

回答

2

就內存管理而言,NSDate的行爲與任何其他對象的行爲不同。你可能指的是使用像[NSDate date]這樣的返回自動釋放對象的便利操作符是常見的(意味着對象將在主循環結束時被刪除(或者當釋放自動釋放池時),除非另一個因爲我看不到你所有的代碼,我只能做出一個有根據的猜測,但我相信你正在調用從[data objectForKey:]返回的對象的釋放,這將是你的錯誤。一個自動釋放的對象,因此在調用retain之前你沒有對象的「所有權」,如果你不調用retain或者明確地分配它,你永遠不應該調用釋放它(這適用於所有對象)。

+0

因此,如果您想保留它,永遠不會在NSDate對象上調用發佈版本?另外如果我正確地理解你,如果我根本不保留一個NSDate的實例,它和釋放它一樣糟糕嗎? – Baza207 2011-03-24 23:32:26

+1

我的朋友,謝謝,謝謝,謝謝,謝謝!這讓我瘋狂了很多年,現在我明白了。 每次我收到日期,我只是把[NSDate日期],所以不保留它。所以現在把它改成[[NSDate date]保留]它清除了所有的東西。 感謝您的幫助。 :-D – Baza207 2011-03-24 23:49:48

+0

你的歡迎:)。如果你想保留一個對象,並保證它將在某個特定類中出現,你應該始終保留它(通過隱式地在init調用中或通過明確的retain調用)。那麼當這個類完成它時,它應該總是調用釋放它,所以它不會泄漏。 – drewag 2011-03-25 02:16:23

0

您遇到的問題是在您的-loadData方法中

dateOpened = [data objectForKey:@"dateOpened"]; 

是上面的行,你直接訪問伊娃,而不是通過將保留的財產。所以你有兩個選擇之一。

// First choice retain it yourself 
dateOpened = [data objectForKey:@"dateOpened"]; 
[dateOpened retain]; 

或者

// Second choice have the @property do it for you 
[self setDateOpened:[data objectForKey:@"dateOpened"]]; 

這就是爲什麼它是讓你知道,當你直接訪問他們使用你的私人高德下劃線是個好主意。你將會有一些錯誤。 :)

// declaring it with underscore would have caught your mistake. 
NSDate *_dateOpened; 
+0

添加下劃線是做什麼的?我注意到當我第一次得到它時,Xcode 4向我推薦了一些其他的東西,但我真的不知道它在做什麼...... – Baza207 2011-03-25 00:13:26

+0

在「首先保留它自己」中,您還應該釋放'dateOpened'事先,如果已經有東西在那裏。此外,保留和分配可以在同一行上完成:'dateOpened = [[data objectForKey:@「dateOpened」] retain];' – user102008 2011-04-19 21:57:16

+0

「在您的私有ivars上使用下劃線,因此您知道何時直接訪問它們。會有一些錯誤。「這根本沒有意義。你「知道」你正在訪問一個屬性,因爲你在代碼中寫了一個點('.');你「知道」你正在訪問一個伊娃,因爲你沒有一個點。即使您恰好將該ivar用作財產,您在設置作爲對象的ivar(代表除外)時也始終保留/釋放。所以你看,它是否被用作財產並不重要;只有在設置實例變量時遵循規則才能保留。 – user102008 2011-04-19 22:05:34

0

的問題loadData是,你是直接分配dateOpened到自動釋放值,一旦事件循環傳遞,這將是無效的。

- (void)loadData 
{ 
NSUserDefaults *data = [NSUserDefaults standardUserDefaults]; 

// dateOpened = [data objectForKey:@"dateOpened"]; 

// try: 
    self.dateOpened = [data objectForKey:@"dateOpened"]; 

// which is basically the same as: 
// [self setDateOpened:[data objectForKey:@"dateOpened"]]; 

// the following 2 lines could also work: 
// [dateOpened release]; 
// dateOpened = [[data objectForKey:@"dateOpened"] retain]; 

} 

如果你有@synthesizeddateOpened,那麼你可以想像,以下2種方法已被添加到您的類:

- (NSDate *)dateOpened { 
    return dateOpened; 
} 

- (void)setDateOpened:(NSDate *)aDate { 
    [aDate retain]; 
    [dateOpened release]; 
    dateOpened = aDate; 
} 
相關問題