2010-01-05 85 views
4

如果我有這樣的代碼如何在iPhone應用程序中可靠地釋放內存?

NSString *postData = [@"foo=" stringByAppendingString:fooText.text]; 
... 
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:url]; 
... 
[postData release]; //this causes crash 
[request release]; //this causes crash 

現在我明白了,這是expected behavior according to Apple's documents。現在,如果我刪除發佈代碼崩潰不會發生,但我發現無論如何內存泄漏*請求。所以我重寫代碼

NSString *postData; 
//postData = [NSString alloc]; // this line commented out since OP 
postData = [@"foo=" stringByAppendingString:fooText.text]; 
... 
NSMutableURLRequest *request; 
request = [NSMutableURLRequest alloc]; 
request = [request initWithURL:url]; 
    ... 
    [postData release]; //this still crashes # 
    [request release]; //this works fine 

我真的不明白爲什麼它會在#處崩潰。這裏有沒有推薦的最佳做法?我認爲我一定會錯過一些東西,因爲我經常看到有一個釋放('Kochan',例如Objective-C中的編程)的'速記'方法(頂部),但是蘋果文檔說這是錯誤的。

回答

7

一般的經驗法則,如果你正在調用輔助靜態方法(如stringByAppendingString),那麼你不應該釋放它。該字符串在被提供給您之前被添加到自動釋放池中。如果您打電話給alloc,則使用init...方法,那麼您負責釋放該對象。

在代碼中要注意的其他事項:

  • 在第二個例子,你ALLOC POSTDATA,然後立即與stringByAppendingString創建另一個字符串替換它,這是一個內存泄漏。
  • 你呼籲釋放是錯誤的,他們應該是[postData release][request release]
  • 我沒有看到postDatarequest之間的相關性在你的榜樣,所以不知道你在跟他們兩個都得到什麼。
+1

「一般的經驗法則,如果你正在調用助手靜態方法(如stringByAppendingString),那麼你不應該釋放它。」那就是我一直在尋找的東西!然而,在第一個例子中,如果儀器指示存在內存泄漏(這全部在一個簡單的方法內),我將如何釋放*請求。這似乎表明autorelease不適用於*請求。 – Gazzer 2010-01-05 09:08:46

+0

在第一個示例中,您自己分配並初始化了請求,因此您應該釋放它。你做什麼事會導致崩潰? EXC_BAD_ACCESS?這通常意味着你已經(或者你提出了請求)已經發布了請求,但你沒有意識到。 – 2010-01-05 17:28:19

0

分配爲對象的內存和初始化它在單行更好地履行 - init方法可能返回不同的對象,也可能有助於避免錯誤你在第二個示例做:

NSString *postData; // Define pointer to string 
postData = [NSString alloc]; // Allocating nsstring pointer and assign it to variable 
postData = [@"foo=" stringByAppendingString:fooText.text]; // assign to postData new **autoreleased** string object. result of the previous assignment is abandoned. 
[postData release]; //so here you release autoreleased object!! 

我想不通爲什麼[equest發佈];儘管在第一個例子中會導致崩潰。

P.S.我沒有完全醒來,或者應該是[postData release]而不是[release postData]

1

首先,在您的第二個示例中,行postData = [NSString alloc];是完全不必要的 - postData被下一行覆蓋。其次,要回答你爲什麼會崩潰的問題 - 沒有好的答案 - 系統可以選擇在保留計數達到0後的任何時候釋放內存。要更輕鬆地調試問題,應該打開NSZombieEnabled,這將立即塗抹解除分配的任何對象,爲您提供100%可靠的方法來測試崩潰。

另外,在單獨的行上分配/ init是不好的樣式。

一般來說,您應該重點關注內存指南。如果你不遵循指導方針,行爲可能是未定義的。

-1
NSString *postData; 
postData = [[NSString alloc]init]; 
postData = [@"foo=" stringByAppendingString:fooText.text]; 
... 
NSMutableURLRequest *request; 
request = [[NSMutableURLRequest alloc]initWithURL:url]; 
... 
    [postData release]; 
    [request release]; 

試試這個。

+0

你的例子仍然有與postdata相同的問題,原來的問題 – Vladimir 2010-01-05 08:51:51

+0

它更好地添加[postData發佈];只要你完成使用該變量。使用後必須釋放內存。 – Nithin 2010-01-05 08:51:52

+1

postData包含第三行賦值後的自動釋放對象 - 您不能釋放它。而你在第二行分配字符串只是簡單地覆蓋它而泄漏。 – Vladimir 2010-01-05 08:58:00

相關問題