开发者

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.

0

上一篇:

下一篇:

精彩评论

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

最新问答

问答排行榜