Errors autoreleasing objects just after their creation
I'm starting to look into IOS Development and I have some doubts about releasing objects for which I did not store a reference.. I gave a look at th开发者_StackOverflowe question "Release an object without a pointer?" where it is suggested to send the autorelease message to the object immediately after its creation, and so I tried to do the same in the following piece of code:
int main(int argc, char *argv[])
{
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
NSURLResponse * response = nil;
NSError * error = nil;
NSData * data;
data = [NSURLConnection
sendSynchronousRequest: [[NSURLRequest requestWithURL:
[[NSURL URLWithString: @"http://www.google.it"]
autorelease]
] autorelease]
returningResponse: &response
error: &error];
[data writeToFile: @"/tmp/test.html"
atomically:NO];
[data release];
[pool drain];
return 0;
}
I could not try to execute the program in XCode yet, but I'm compiling under linux and the autorelease message sent to the NSURLRequest object causes a segmentation error (I think it is not caused by the message itself but by the pool drain that tries to release the object, due to the autorelease message). What's wrong with the autorelease message I've sent to the NSURLRequest object?
I think that if the reference doc for a class method like requestWithUrl says that it "Creates and returns a URL request" it means that I'm responsible to release the object when I've finished using it, am I wrong? I'd like to understand very well this memory management rules before going further with anything else.. I hope my questions are not too stupid ;-)
Uh, just one last question: should I release also the error and data objects returned by the synchrounous request?
Thank you in advance for any help!
+requestWithURL:
(and other) methods already return autoreleased objects so you should not send one more autorelease to them.
Extra autoreleases in your code make object over-released later and make app crash.
Rule of thumb to know if you must release an object - release required only if you create object using method that contains 'alloc', 'new', 'copy' in its name. All standard APIs follow this rule and you should follow it when developing your own methods.
So corrected code will be:
int main(int argc, char *argv[])
{
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
NSURLResponse * response = nil;
NSError * error = nil;
NSData * data;
data = [NSURLConnection
sendSynchronousRequest: [NSURLRequest requestWithURL:
[NSURL URLWithString: @"http://www.google.it"]
returningResponse: &response
error: &error];
[data writeToFile: @"/tmp/test.html"
atomically:NO];
[pool drain];
return 0;
}
P.S. Neither data and error objects should be released for the above reasons.
Your code should look like this:
int main(int argc, char *argv[])
{
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
NSURLResponse * response = nil;
NSError * error = nil;
NSData * data;
data = [NSURLConnection
sendSynchronousRequest: [NSURLRequest requestWithURL:[NSURL URLWithString: @"http://www.google.it"]] returningResponse:&response error: &error];
[data writeToFile: @"/tmp/test.html"
atomically:NO];
[pool drain];
return 0;
}
You don't need to call autorelease
to your objects created with that methods.\
You don't need to release data
and error
.
All methods that returns object using next notation NSClass *object = [NSClass classSomeMagicWords];
will return autoreleased object, which you should not release if you don't call retain
.
You should remove the autoreleases. In the iOS/Mac OSX dev, with the Classes supplied by Apple it’s pretty much the rule that if you’re creating an object with a method that does not involve the word init, you’re given an already autoreleased object.
For example:
NSString *blaah = [[NSString alloc] init];
Would return an object that you need to release later.
NSURL *googlelink = [NSURL URLWithString: @"http://www.google.it"];
on the other hand will give you an autoreleased object and if you release it again, it will crash.
In iOS memory management, you only own objects you create by allocating memory for it or copying it (methods either starts with alloc or have "copy" in its name).
You only need to release/autorelease them if you own them. Methods such as requestWithURL
or URLWithString
returns already autoreleased objects.
Check this doc from Apple developer site for more information.
精彩评论