开发者

NSURLConnection leak issues

As a disclaimer I'd like to state that I'm fairly new to Objective-C and Cocoa. Currently I'm trying to write a basic application that can POST XML data to a particular endpoint. To achieve this, I've created a ServiceRouter class which uses NSURLConnection to post XML data to a particular URL.

The ServiceRouter class is intended as a base for subclasses which contain webservice-specific XML queries. In the example below, I subclass ServiceRouter to create a ServiceImplementation class.

When it's time to generate and POST the XML, I create an instance of the ServiceImplementation class like so:

[[ServiceImplementation alloc] createServiceSpecificXML];

This all seems to work fine. The issue is that Leaks reports a number of issues. Being fairly inexperienced, I'm not really sure where to start. For the most part, the NSURLConnection code is lifted from Apple's documentation.

Following basic memory management rules, I imagine I will have to release my ServiceImplementation instance at some point. What I'm confused about is how this should be han开发者_JAVA技巧dled given the asynchronous nature of NSURLConnection. Is this a candidate for autorelease?

I'm hoping that someone with more Objective-C/Cocoa experience can look things over and tell me if I'm moving in the right direction.

Here's the ServiceRouter class:

@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

Here's my ServiceImplementation class:

@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


You never initialize the instance. Merely allocing is not sufficient. You must call init or some other initializer — preferably on the same line as alloc.

From your (working but odd) construct of [[NSMutableData data] retain], I'm going to guess you haven't read a lot of Apple's basic primers. I would recommend at least The Objective-C Programming Language and the memory management guide. Neither is very long, and between these two, I think you'll clear up a lot of your uncertainties.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜