Reputation: 4656
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;
//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
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.
Upvotes: 4
Views: 650
Reputation: 6475
NSString *postData;
postData = [[NSString alloc]init];
postData = [@"foo=" stringByAppendingString:fooText.text];
...
NSMutableURLRequest *request;
request = [[NSMutableURLRequest alloc]initWithURL:url];
...
[postData release];
[request release];
Try this.
Upvotes: -1
Reputation: 25022
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.
Upvotes: 1
Reputation: 62057
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:
stringByAppendingString
, that is a memory leak.[postData release]
and [request release]
postData
and request
in your example, so not sure exactly what you are getting at with the two of them.Upvotes: 7
Reputation: 170859
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]
?
Upvotes: 0