Проблемы утечки NSURLConnection - PullRequest
       7

Проблемы утечки NSURLConnection

0 голосов
/ 17 апреля 2010

Как заявление об отказе от ответственности, я хотел бы заявить, что я довольно плохо знаком с Objective-C и Cocoa. В настоящее время я пытаюсь написать базовое приложение, которое может POST XML-данные для конкретной конечной точки. Чтобы достичь этого, я создал класс ServiceRouter, который использует NSURLConnection для публикации данных XML на определенный URL-адрес.

Класс ServiceRouter предназначен в качестве основы для подклассов, которые содержат специфичные для веб-службы XML-запросы. В приведенном ниже примере я создаю подкласс ServiceRouter для создания класса ServiceImplementation.

Когда приходит время генерировать и POST XML, я создаю экземпляр класса ServiceImplementation так:

[[ServiceImplementation alloc] createServiceSpecificXML];

Кажется, все работает нормально. Проблема в том, что Leaks сообщает о ряде проблем. Будучи довольно неопытным, я не совсем уверен, с чего начать. По большей части код NSURLConnection взят из документации Apple.

Следуя основным правилам управления памятью, я полагаю, что в какой-то момент мне придется выпустить свой экземпляр ServiceImplementation. Что меня смущает, так это то, как это следует обрабатывать, учитывая асинхронный характер NSURLConnection. Это кандидат на авто-релиз?

Я надеюсь, что кто-то с большим опытом Objective-C / Cocoa сможет осмотреть вещи и сказать мне, двигаюсь ли я в правильном направлении.

Вот класс ServiceRouter:

@interface ServiceRouter : NSObject {
    NSMutableData *receivedData;
}

-(void)postXMLToURL:(NSString *)url xml:(NSString *)xmlData;
-(void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response;
-(void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data;
-(void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error;
-(void)connectionDidFinishingLoading:(NSURLConnection *)connection;
@end

@implementation ServiceRouter

- (void)postXMLToURL:(NSString *)url xml:(NSString *)xmlData
{
    NSLog(@"Posting XML to URL: %@", url);

    NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:url]];
    [request setHTTPMethod:@"POST"];
    [request setValue:@"application/xml" forHTTPHeaderField:@"Content-type"];
    [request setValue:@"application/xml" forHTTPHeaderField:@"Accept"]; 

    [request setValue:[NSString stringWithFormat:@"%d", [xmlData length]] forHTTPHeaderField:@"Content-length"];
    [request setHTTPBody:[xmlData dataUsingEncoding: NSUTF8StringEncoding]];

    NSURLConnection *connection = [[[NSURLConnection alloc] initWithRequest:request delegate:self] autorelease];
    if(connection) {
        NSLog(@"Connection created");
        receivedData = [[NSMutableData data] retain];
    } else {
        NSLog(@"Issue with connection!");
    }
}

-(void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
    if([response respondsToSelector:@selector(statusCode)])
    {
        int statusCode = [((NSHTTPURLResponse *)response) statusCode];
        NSLog(@"HTTP Response code: %i", statusCode);
    }
    NSLog(@"Received response");
    [receivedData setLength:0];
}

-(void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
    NSLog(@"Received data: %@", data);
    [receivedData appendData:data];
}

-(void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
    [connection release];
    [receivedData release];

    NSLog(@"Connection failed! Error - %@", [error localizedDescription]);
}

-(void)connectionDidFinishingLoading:(NSURLConnection *)connection
{
    NSLog(@"Succeeded! Received %d bytes of data", [receivedData length]);

    [connection release];
    [receivedData release];
}
@end

Вот мой класс ServiceImplementation:

@interface ServiceImplementation : ServiceRouter {
}
-(void) createServiceSpecificXML;
@end

@implementation ServiceImplementation

-(void) createServiceSpecificXML
{
    NSString *xmlData = @"<example><ignore/></example>";
    [super postXMLToURL:@"http://site.com/endpoint.xml" xml:xmlData];
}

@end

1 Ответ

1 голос
/ 17 апреля 2010

Вы никогда не инициализируете экземпляр. Простого выделения недостаточно. Вы должны вызвать init или другой инициализатор - предпочтительно на той же строке, что и alloc.

Исходя из вашей (работающей, но странной) конструкции [[NSMutableData data] retain], я предполагаю, что вы не читали много основных учебников Apple. Я бы рекомендовал Язык программирования Objective-C и руководство по управлению памятью . Ни один из них не очень длинный, и между этими двумя, я думаю, вы проясните большую часть своих неопределенностей.

...