为什么这里的发布声明会破坏应用程序?

时间:2011-08-31 08:11:18

标签: iphone objective-c http

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 : %@", theResponse);
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

是否与此声明有关:NSData *data = [NSURLConnection sendSynchronousRequest:request returningResponse:&theResponse error:&theError]; 我看到使用了&符号。这意味着什么?

3 个答案:

答案 0 :(得分:3)

在您编辑问题时,我会将此作为新答案发布。

你这样做是错误的。

sendSynchronousRequest:returningResponse:error:负责为您创建响应(如果出现错误,则为错误)

这就是为什么你需要传递指向theResponse的指针和指向theError的指针

完成对sendSynchronousRequest:returningResponse:error:的调用后,theResponse将被创建,最重要的是autoreleasedsendSynchronousRequest:returningResponse:error)!!

所以最后你回到了autorelease / over release问题。

正确的代码是:

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

答案 1 :(得分:1)

嗯,当你实例化它时自动释放theResponse,因此释放它两次会导致你的问题。要么不进行autorelease来电,要么不进行release来电。

就个人而言,我会摆脱autoreleaserelease可以对程序的运行进行更精细的控制。

哦,&没有什么可担心的 - 它只是传递了它所进行的变量的地址。在这种情况下,您需要传递NSURLResponse**。由于您有NSURLResponse*,因此您可以将引用传递给它。

答案 2 :(得分:1)

这是因为theResponse已将消息autorelease发送到:

NSURLResponse *theResponse =[[[NSURLResponse alloc]init] autorelease];

如果release对象已经autoreleased,那么您的应用程序将崩溃,垃圾收集器将过度释放该对象。

&只是意味着“给我theErrortheResponse的地址(基本上你传递方法sendSynchronousRequest:returningResponse:error:所需的指针指针<) / p>

+ (NSData *)sendSynchronousRequest:(NSURLRequest *)request 
                 returningResponse:(NSURLResponse **)response
                             error:(NSError **)error

NSURLResponse **NSError **表示“地址”,因此只提供theErrortheResponse(不包含&)只会提供方法当他们期待别的东西时,他们的“地址”。