Потеря данных ответа в оболочке NSURLConnection - PullRequest
0 голосов
/ 25 января 2012

У меня возникли проблемы с реализацией оболочки NSURLConnection.Я создаю NSURLConnection с данными POST, и соединение, кажется, получает ответ, а также данные.Обратный вызов didReceiveData регистрирует длину responseData, которая составляет 2000 байтов.Однако к моменту запуска didFinishLoading responseData содержит 0 байтов.Любые советы о том, где искать то, что может быть изменение содержимого responseData?Он сбрасывается в didReceiveResponse, но, по-видимому, didReceiveResponse не вызывается между didReceiveData и didFinishLoading.

Вот некоторые выводы из журнала:

Текущий язык: auto;текущая цель-c 2012-01-24 13: 35: 40.020 PSIdea [24007: 11903] didReceiveResponse: responseData length: (0)
предупреждение: попытка создать переменную USE_BLOCK_IN_FRAME с блоком, который не находится в кадре.2012-01-24 13: 35: 40.604 PSIdea [24007: 11903] didReceiveData.длина responseData: (2233) 2012-01-24 13: 35: 40.604 PSIdea [24007: 11903] didFinishLoading: длина responseData: (0)
2012-01-24 13: 35: 41,881 PSIdea [24007: 11903] responseDataв виде строки:
2012-01-24 13: 35: 41.882 PSIdea [24007: 11903] responseData в виде словаря:

Вот соответствующий код:

NetworkController.m

-(void)postRequestToURL:(NSURL*)url withData:(NSData*)data withContentType:(NSString*)contentType 
{
    NSMutableURLRequest* request = [NSMutableURLRequest requestWithURL:url];
    [request setHTTPMethod:@"POST"];
    if (!contentType)
    {
        contentType = @"application/x-www-form-urlencoded";
    }
    [request setValue:contentType forHTTPHeaderField:@"Content-Type"];
    [request setHTTPBody:data];
    [[NSURLConnection alloc] initWithRequest:request delegate:self];
}

-(void)connection:(NSConnection*)conn didReceiveData:(NSData*)data 
{
    [_responseData appendData:data];
    NSLog(@"didReceiveData. responseData length:(%d)", _responseData.length);
}

-(void)connection:(NSConnection*)conn didReceiveResponse:(NSURLResponse *)response 
{
    if (_responseData == NULL) {
        _responseData = [[NSMutableData alloc] init];
    }
    [_responseData setLength:0];
    NSLog(@"didReceiveResponse: responseData length:(%d)", _responseData.length);
}


-(void)connection:(NSConnection*)conn didFailWithError:(NSError *)error 
{
    NSLog([NSString stringWithFormat:@"Connection failed: %@", error.description]);
}

PSINetworkController.m (подкласс)

-(void)connectionDidFinishLoading:(NSURLConnection*)connection
{
    NSLog(@"didFinishLoading: responseData length:(%d)", _responseData.length);
    NSString *responseString = [[NSString alloc] initWithData:_responseData encoding:NSUTF8StringEncoding];
    NSLog(@"responseData as string: %@", responseString);
    SBJsonParser* parser = [[SBJsonParser alloc] init];
    NSDictionary* dict = [parser objectWithData:_responseData];
    NSLog(@"responseData as dictionary:");
    for (id key in dict) {
        NSLog(@"%@=%@", key, [dict objectForKey:key]);
    }
    [_delegate connection:connection receivedResponse:dict];
}

Спасибо.

РЕДАКТИРОВАТЬ: Кроме того, я, кажется, наткнулся на решение.Эта проблема как-то связана со способом объявления _responseData.

Объявление данных ответа в качестве атомарного свойства приводит к сбросу данных ответа, как и раньше.

@property (retain) NSMutableData* responseData;

Однако простообъявление переменной в интерфейсе, кажется, устраняет проблему - данные сохраняются от didReceiveData к didFinishLoading.

@interface NetworkController : NSObject
{
    NSMutableData* _responseData;
}

Насколько я понимаю, объявление свойств просто генерирует сеттеры и геттеры, но я не вижу, какэто относится к этой ситуации.Кто-нибудь может объяснить?

РЕДАКТИРОВАТЬ: я забыл упомянуть, что этот проект использует ARC.

1 Ответ

0 голосов
/ 25 января 2012

если вы объявили responseData как сохраняемый, если ваш файл .h, вы должны изменить код на:

-(void)connection:(NSConnection*)conn didReceiveResponse:(NSURLResponse *)response 
{
    if (self._responseData) {
            self._responseData = [[NSMutableData alloc] init] autorelease];
        }
//further code
}

это должно решить вашу проблему

...