objective-c - NSURLConnection 泄漏问题

标签 objective-c cocoa memory-leaks nsurlconnection

作为免责声明,我想声明我对 Objective-C 和 Cocoa 还很陌生。目前,我正在尝试编写一个基本应用程序,可以将 XML 数据发布到特定端点。为了实现这一点,我创建了一个 ServiceRouter 类,它使用 NSURLConnection 将 XML 数据发布到特定的 URL。

ServiceRouter 类旨在作为包含特定于 Web 服务的 XML 查询的子类的基础。在下面的示例中,我将 ServiceRouter 子类化以创建 ServiceImplementation 类。

当需要生成并发布 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

最佳答案

您永远不会初始化该实例。仅仅分配是不够的。您必须调用 init 或其他一些初始化程序 - 最好与 alloc 在同一行。

从你的(有效但奇怪的)[[NSMutableData data]retain]构造来看,我猜你还没有读过很多苹果的基本入门书。我至少推荐The Objective-C Programming Languagememory management guide 。两者都不是很长,在这两者之间,我想你会消除很多不确定性。

关于objective-c - NSURLConnection 泄漏问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2656013/

相关文章:

objective-c - SOLID 原则如何应用于 Objective-C 中的方法覆盖?

objective-c - 如何在 Mac 上获取当前设备

macos - 在控制台应用程序中使用 swift 处理 cocoa 键事件(按下键)

memory-leaks - 为什么启用 Firebug 会发生内存泄漏?

c++ - C++ dll中的内存泄漏

google-app-engine - 在 GAE 1.7.3 中使用 DeferredTasks 时用完 PermGen 空间

iOS 获取两个字符串之间的字符串

ios - 当用户使用长按手势时如何在 Collection View 单元格中显示按钮。

ios - 对从核心数据中获取的对象进行变音符号敏感排序?

objective-c - 查找方法的调用位置