如何在iPhone应用程序中可靠地释放内存?

时间:2010-01-05 08:23:18

标签: iphone memory

如果我有这段代码

 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编程),但Apple文档说这是错误的。

4 个答案:

答案 0 :(得分:7)

一般的经验法则,如果你正在调用辅助静态方法(例如stringByAppendingString),那么就不应该释放它。在给予您之前,该字符串已添加到自动释放池中。如果您正在调用alloc然后调用init...方法,那么您有责任释放该对象。

您的代码中需要注意的其他事项:

  • 在第二个示例中,您分配postData,然后立即将其替换为stringByAppendingString创建的另一个字符串,即内存泄漏。
  • 您的发布通话错误,应该是[postData release][request release]
  • 我在您的示例中看不到postDatarequest之间存在任何关联,因此不确定您对这两者的确切了解。

答案 1 :(得分:1)

首先,在第二个示例中,行postData = [NSString alloc];完全没必要 - postData会被下一行覆盖。第二,回答关于为什么事情崩溃的问题 - 没有好的答案 - 系统可以选择在保留计数达到0后随时释放内存。为了更容易地调试问题,你应该打开NSZombieEnabled ,它将立即乱写任何已解除分配的对象,为您提供100%可靠的测试崩溃方法。

另外,在单独的行上分配/ init是不好的风格。

通常,您应该专注于遵循内存准则。如果您不遵守这些准则,则行为可能未定义。

答案 2 :(得分: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 release];但是在第一个例子中导致崩溃。

P.S。我没有完全醒来,或者它应该是[postData release]而不是[release postData]

答案 3 :(得分:-1)

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

试试这个。