2010-01-05 59 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

相关问题