开发者

How do I reliably release memory in iPhone app?

If I have this code

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

Now I understand this is the expected behavior according to Apple's documents. Now if i remove the release code the crash doesn't happen but I find that the memory leaks anyway for *request. So I rewrite the code

NSString *postData;
//po开发者_JAVA百科stData = [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

I don't really understand why it would crash at # . Is there any recommended best practice here? I think I must be missing something because I often see the 'shorthand' approach (top) having a release (Kochan, Programming in Objective-C for example), but the Apple docs say that it's wrong.


The general rule of thumb, if you are calling a helper static method (such as stringByAppendingString), then you shouldn't release it. That string was added to an autorelease pool before being given to you. If you are calling alloc then an init... method, then you are responsible for releasing that object.

Other things to note in your code:

  • In the second example, you alloc postData, then immediately replace it with another string created by stringByAppendingString, that is a memory leak.
  • Your release calls are wrong, they should be [postData release] and [request release]
  • I don't see any correlation between postData and request in your example, so not sure exactly what you are getting at with the two of them.


First, in your second example, the line postData = [NSString alloc]; is completely unnecessary - postData is overwritten by the next line. Second, to answer your question as to why things crash - there is no good answer - the system can choose to free up memory anytime after the retain count hits 0. To more easily debug the issue, you should turn on NSZombieEnabled, which will immediately scribble any objects which are deallocated, giving you a 100% reliable way to test crashes.

Also, it is bad style to alloc/init on separate lines.

In general, you should focus on following the memory guidelines. If you're not following the guidelines, behavior can be undefined.


Allocating memory for your object and initializing it better perform in single line - init method may return different object and also it may help to avoid mistake you've made in 2nd example:

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!!

I cannot figure out why [equest release]; causes crash in the 1st example though.

P.S. I'm not completely wake up or it should be [postData release] instead of [release postData] ?


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

Try this.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜