Why did the release statement here crashes the app?
NSError *theError = nil;
NSArray *keys = [NSArray arrayWithObjects:@"password", @"userId", nil];
NSArray *objects = [NSArray arrayWithObjects:passwordTextField.text, userNameTextField.text, nil];
NSDictionary *requestDictionary = [NSDictionary dictionaryWithObjects:objects forKeys:keys];
NSString *JSONString =[requestDictionary JSONRepresentation];
NSData *JSONData =[JSONString dataUsingEncoding:NSUTF8StringEncoding];
NSLog(@"JSONString :%@", JSONString);
NSLog(@"JSONData :%@", JSONData);
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:@"http://153.20.32.74/11AprP306/passenger/jsonitem"]];
[request setValue:@"application/json" forHTTPHeaderField:@"Content-Type"];
[request setHTTPBody:JSONData];
[request setHTTPMethod:@"POST"];
NSURLResponse *theResponse =[[NSURLResponse alloc]init];
NSData *data = [NSURLConnection sendSynchronousRequest:request returningResponse:&theResponse error:&theError];
NSLog(@"response : %@", theRespo开发者_StackOverflow中文版nse);
NSLog(@"error : %@", theError);
NSLog(@"data : %@", data);
NSMutableString *string = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSLog(@"string: %@", string);
[string release];
//[theResponse release]; // this statement crashes the app
Has it got something with to do with this statement :NSData *data = [NSURLConnection sendSynchronousRequest:request returningResponse:&theResponse error:&theError];
I see a &
symbol used. What does it means?
I'll post this as a new answer as you edited your question.
You are doing it the wrong way.
It is the responsability of sendSynchronousRequest:returningResponse:error:
to create the response for you (or the error if something went wrong)
This is why you need to pass a pointer to theResponse
and a pointer to theError
When the call to sendSynchronousRequest:returningResponse:error:
is done, theResponse
will be created and most importantly autoreleased
(by sendSynchronousRequest:returningResponse:error
) !!
So in the end you are back to the autorelease/over release issue.
The correct code is:
NSURLResponse *theResponse = nil; // no need to init it will be done later on
NSError *theError = nil; // no need to init either
NSData *data = [NSURLConnection sendSynchronousRequest:request
returningResponse:&theResponse
error:&theError];
if (aError != nil) { } // handle error
else {} // handle your response data
//no need to release theResponse
Well, you autorelease theResponse
when you instantiate it, so releasing it twice is causing your problem. Either don't make the autorelease
call or don't make the release
call.
Personally, I'd get rid of the autorelease
. release
gives finer-grained control over the run of your program.
Oh, and the &
there is nothing to worry about -- it just passes the address of the variable it proceeds. In this case, you need to pas an NSURLResponse**
. Since you have an NSURLResponse*
, you pass a reference to it.
This is because theResponse
has sent the message autorelease
in:
NSURLResponse *theResponse =[[[NSURLResponse alloc]init] autorelease];
If you release
an object that has been autoreleased
you will cause your application to crash for the Garbage Collector will over release the object.
The &
simply means "give me the address of theError
and theResponse
(basically you are passing a pointer of pointer which is required by the method sendSynchronousRequest:returningResponse:error:
)
+ (NSData *)sendSynchronousRequest:(NSURLRequest *)request
returningResponse:(NSURLResponse **)response
error:(NSError **)error
The NSURLResponse **
and NSError **
means 'address of address' so give them only theError
or theResponse
(without the &
) would simply give the method 'their address' when it is expecting something else.
精彩评论