作为目标C的初学者,我正在实现一个查询Web服务器并在控制台中显示返回字符串的函数。我在循环中重复调用函数(getDatafromServer)。问题是第一次获取值而其他时候,它在控制台中返回一个(null)...我搜索了内存管理并在论坛上查看但没有一个有效。你能告诉我下面的代码哪里出错了吗?提前谢谢....
@implementation RequestThread
+(void)startthread:(id)param{
while (true) {
//NSLog(@"Test threads");
sleep(5);
NSLog(@"%@",[self getDatafromServer]);
}
}
+(NSString *) getDatafromServer{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
NSString *myRequestString = @"name=Hello%20&email=essssss@live.com";
NSData *myRequestData = [NSData dataWithBytes:[myRequestString UTF8String] length:[myRequestString length]];
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL: [NSURL URLWithString:@"http://192.168.1.32/gs/includes/widget/getcalls.php?user=asdasd&passw=asdasdasd"]];
[request setHTTPMethod:@"POST"];
[request setHTTPBody: myRequestData];
[request setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"content-type"];
NSData *returnData = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];
NSString *myString = [NSString stringWithUTF8String:[returnData bytes]];
[myRequestString release];
[request release];
[returnData release];
return myString;
[pool release];
}
@end
答案 0 :(得分:1)
在这个函数中使用自动释放池是个坏主意,并在'return'之后释放它。 删除池,一切都应该没问题。
答案 1 :(得分:1)
您遇到自动释放池问题。首先,正如尼古拉所说,释放永远不会发生,因为它是在返回之后。我很惊讶你没有看到编译器警告。确保将-Wall
设置为“其他警告标志”,并设置“运行静态分析器”构建选项。
由于您希望在函数外部使用返回的字符串,因此自动释放池也必须位于函数外部,或者在日志到达之前可以取消分配字符串。您的代码结构应该更像:
+(void)startthread:(id)param
{
while (true)
{
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
//NSLog(@"Test threads");
sleep(5);
NSLog(@"%@",[self getDatafromServer]);
[pool drain]; // use instead of release in case you move to GC
}
}
您遇到的另一个问题是您没有进行任何错误检查。你怎么能确定:
你需要检查一下returnData是否为nil,你需要检查NSError。所以你需要这样的东西:
NSError* error = nil;
NSData *returnData = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:&error];
if (returnData == nil)
{
the error object will be set and contain useful info.
}
您还需要检查myString是否为零。如果是,那将是因为响应未被编码为UTF-8。使用HTTP,默认编码不是UTF-8,而是ISO-8859-1。此外,响应的主体可能根本不是字符数据。您需要检查响应以找出如何解码数据。所以我上面发布的代码片段看起来应该是这样的:
NSError* error = nil;
NSURLResponse* response = nil;
NSData *returnData = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];
if (returnData == nil)
{
// the error object will be set and contain useful info.
}
else
{
// You can get the content type and encoding from the response here.
}
修改
此外,您的代码违反了Memory Management Rules。您没有通过alloc,copy或new获取myRequestString
或returnData
,也没有保留它们,因此不得释放它们。