Objective C: Function returning correct data for the first time of call and null for other times
Am a beginner in objective C, i am implementing a function that would query a web server and display the returning string in console. I am calling the function (getDatafromServer) repeatedly in a loop. The problem is that the first time am getting the value whereas the other times, it returns me a (null) in console... I've searched about memory management and check out on the forums but none have worked. Can you please guys tell me where am wrong in the codes below? Thanks in advance....
@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 UTF8开发者_开发技巧String] 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
You have a problem with the autorelease pool. Firstly, as Nickolay has said, the release never happens because it is after the return. I'm amazed you aren't seeing compiler warnings. Make sure you have -Wall
set in "other warning flags" and you have the "Run static analyzer" build option set.
Since you want to use the returned string outside of the function, the autorelease pool must also be outside the function, or the string may be deallocated before your log gets to it. Your code structure should look more like:
+(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
}
}
The other problem you have is that you are not doing any error checking. How can you be sure that:
- the request to the server is working?
- the response from the server is encoded as UTF-8.
You need to check if returnData is nil after you get it and you need to examine the NSError if it is. So you need something like this:
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.
}
You also need to check if myString is nil. If it is, it will be because the response was not encoded as UTF-8. With HTTP the default encoding is not UTF-8, it is ISO-8859-1. Also, the body of the response might not be character data at all. You need to examine the response to find out how to decode the data. So the code snippet I posted above should really look like:
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.
}
Edit
Also, your code violates the Memory Management Rules. You did not obtain myRequestString
or returnData
through alloc, copy or new, neither have you retained them, so you must not release them.
That's bad idea to use autorelease pool in this function, and release it after 'return'. Remove pool and everything should be ok.
精彩评论