目标C:函数在第一次调用时返回正确的数据,而在其他时间返回null

时间:2011-01-13 06:42:12

标签: objective-c function memory-management nsstring

作为目标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

2 个答案:

答案 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
    }
}

您遇到的另一个问题是您没有进行任何错误检查。你怎么能确定:

  • 对服务器的请求是否有效?
  • 来自服务器的响应编码为UTF-8。

你需要检查一下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获取myRequestStringreturnData,也没有保留它们,因此不得释放它们。