2010-03-23 32 views
1

我見過的代碼類似的一行浮動約在蘋果代碼:內存泄漏使用(無效)ALLOC

(void)[[URLRequest alloc] initializeRequestWithValues:postBody url:verifySession httpHeader:nil delegate:self]; 

的URLRequest是我自己的自定義類。我沒有寫這篇文章,我想那個剛剛從蘋果公司的例子中拿出來的人。對我來說,這應該泄漏,當我測試它時,我確信它泄漏了16個字節。會嗎?我知道如何解決它,但不知道它是從Apple的代碼中得到的。

編輯:問題是與SDK,而不是上述代碼。請參閱下面的答案以獲取更多詳細信息

+0

我會/不會/使用任何代碼以'-initializeSomething'開始的方法:任何人不知道足夠的Objective-C來命名他們的方法'-initSomething'可能不會正確地避免泄漏:可能聽起來很刺耳,像這樣的一個簡單的錯誤可能實際上表明對工具集不熟悉。 – 2010-03-23 03:53:26

+1

:/雖然你有一個點不是一個挑選?他可能會對縮短單詞充滿激情。其餘的代碼不會泄漏 – Rudiger 2010-03-23 04:25:35

+0

Rudiger:遵循適當的命名約定是/總是/一個好主意。 – 2010-03-25 01:04:58

回答

3

想到我可能會更新此版本,因爲經過進一步測試以及iOS4發行版發生了變化。

上面的代碼不會泄漏,即使經過200次代碼迭代,應用程序的內存佔用量也會恢復正常。這種泄漏確實發生在iOS3中,但非常小,在iOS4中它已經在模擬器和設備中完全消失。

有些人可能會想知道爲什麼要實現這些代碼,但它在處理同時運行的代碼中的許多不同的NSURLConnections時很有用。

2

完全不知道該代碼應該完成什麼。它似乎打破了關於初始化方法的每一個約定。從初始化方法返回一個void指針有什麼意義?初始化方法的全部要點是返回一個對象。在蘋果的代碼示例中,你看到了這個嗎?

話雖如此,我不明白它爲什麼會泄漏。由於它不返回對象,因此該方法不會泄露任何內容。有可能是內部泄露的東西。

編輯:

It basically does an NSURLConnection. Because we are submitting a lot of forms with a lot of different values we put it in an external class. All the delegate methods like didFailWithError: are in NSURLRequest and connectionDidFinishLoading just passes the data to its delegate. So it doesn't really need to return anything as it is done through a delegate method.

是的,你需要重新設計這一點。目前,這種方法只是一場等待發生的災難。如果沒有別的,看着這個代碼的其他人都會對你在做什麼感到困惑。

如果您不需要保留創建的對象,然後移動它的分配並完全在一個方法內清理。將方法名稱前綴從「initialize」更改爲「setup」,「configure」,「acquire」等等,這樣的名稱並不意味着它會創建並返回對象。

如果您需要某個特定類的一次性實例,請使用類似Michael Aaron Safyan建議的類方法(同樣不要在名稱中初始化)。類方法應該在內部初始化一個實例,執行所需的操作,返回數據到任何地方,然後釋放實例。

這樣,您就不必擔心泄漏,並且可能會讀取您的代碼的其他人(包括您自己的月份)都會立即明白代碼的作用。

+0

它基本上做一個NSURLConnection。因爲我們提交了許多具有很多不同值的表單,所以我們把它放在一個外部類中。像didFailWithError這樣的所有委託方法都在NSURLRequest中,而connectionDidFinishLoading只是將數據傳遞給它的委託。所以它不需要返回任何東西,因爲它是通過委託方法完成的。 – Rudiger 2010-03-23 05:00:42

+0

是的。我花了很長時間才弄清楚,然後這個傢伙向我展示了Apple從他得到的代碼。想想我可能會放棄整個事情並重新開始。 – Rudiger 2010-03-23 23:20:42

2

是的。這是一個漏洞,它可以很容易地通過添加一個自動修復:

 
[[[URLRequest alloc] initializeRequestWithValues:postBody url:verifySession httpHeader:nil delegate:self] autorelease]; 

也許是更好的解決將是創建一個類的功能,這是否:

 
@interface URLRequest 
{ 
    // ... 
} 
// ... 
+ (void) requestWithValues:/* ... */ 
// ... 
@end 

然後,你可以簡單地使用[ URLRequest requestWithValues:/ * ... * /]而不調用alloc。

+0

我實際上無法調用autorelease,因爲URLRequest中的NSURLConnection可能會在運行循環後響應。我試過了,它崩潰了。我會考慮你的其他修復,因爲它聽起來更好。 – Rudiger 2010-03-23 07:08:09

+0

@Rudiger,如果您需要實例持久化,那麼您應該將其另存爲使用它的對象的成員,並在dealloc方法中使用該成員的正常版本。 – 2010-03-23 07:20:09

+0

+1類方法絕對是一種方法 – TechZen 2010-03-23 13:06:14