Цель C: функция, возвращающая правильные данные в первый раз вызова и ноль для других времен - PullRequest
0 голосов
/ 13 января 2011

Я новичок в цели C, я реализую функцию, которая будет запрашивать веб-сервер и отображать возвращаемую строку в консоли. Я вызываю функцию (getDatafromServer) несколько раз в цикле. Проблема в том, что в первый раз я получаю значение, тогда как в другое время он возвращает мне (ноль) в консоли ... Я искал об управлении памятью и проверял на форумах, но ни один не помог Ребята, подскажите, пожалуйста, где я не прав в кодах ниже? Заранее спасибо ....

@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 ]

1 голос
/ 13 января 2011

У вас проблема с пулом автоматического выпуска.Во-первых, как сказал Николай, освобождение никогда не происходит, потому что это после возвращения.Я поражен, что вы не видите предупреждений компилятора.Убедитесь, что вы установили -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 ноль после того, как вы его получили, и вам нужно проверить, есть ли ошибка NSE.Поэтому вам нужно что-то вроде этого:

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 значение nil.Если это так, то это будет потому, что ответ не был закодирован как 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.
}

Редактировать

Кроме того, ваш код нарушает Правила управления памятью .Вы не получили myRequestString или returnData через alloc, copy или new, а также не сохранили их, поэтому вы не должны выпускать их.

1 голос
/ 13 января 2011

Это плохая идея использовать пул автоматического освобождения в этой функции и освобождать его после возврата.Удалить пул и все должно быть в порядке.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...