NSURLConnection泄漏?

时间:2009-08-28 08:15:04

标签: objective-c memory-management memory-leaks nsurlconnection nsurlrequest

我已经设置了一个nsurl,它从http中获取数据。 当我运行仪器时,它说我有一个泄漏的NSFNetwork对象。

如何在(void)ButtonClicked中发布 theConnection ?或者它会在稍后发布?

- (void)ButtonClicked {
    NSURLRequest *theRequest = [NSURLRequest requestWithURL:[NSURL URLWithString:KmlUrl]
                                                cachePolicy:NSURLRequestUseProtocolCachePolicy
                                            timeoutInterval:20.0f];

    NSURLConnection *theConnection = [[NSURLConnection alloc] initWithRequest:theRequest delegate:self];
    if (theConnection) {
        // receivedData is declared as a method instance elsewhere
        NSMutableData *receivedData = [[NSMutableData data] retain];
        [self setKMLdata:receivedData];
    } else {
        // inform the user that the download could not be made
    }
}


- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
    // append the new data to the receivedData
    // receivedData is declared as a method instance elsewhere
    [KMLdata appendData:data];
    NSLog(@"didReceiveData");
}


- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
    // release the connection, and the data object
    [connection release];
    [KMLdata release];
}


- (void)connection:(NSURLConnection *)connection  didFailWithError:(NSError *)error
{
    // release the connection, and the data object
    [connection release];
    // receivedData is declared as a method instance elsewhere
    [KMLdata release];

}

4 个答案:

答案 0 :(得分:17)

我终于找到了答案。

上述代码中的错误(顺便说一下,来自SDK docs的近似精确样本)不在内存管理代码中。自动释放是一种选择,手动释放是另一种选择。无论您如何处理NSURLConnection对象,都会使用NSURLConnection进行泄漏。

首先,这是解决方案。只需将这3行代码直接复制到connectionDidFinishLoading,didFailWithError以及释放NSURLConnection对象的任何其他位置。

NSURLCache *sharedCache = [[NSURLCache alloc] initWithMemoryCapacity:0 diskCapacity:0 diskPath:nil];
[NSURLCache setSharedURLCache:sharedCache];
[sharedCache release];

感谢http://forums.macrumors.com/showthread.php?t=573253上的 mpramodjain 代码。

问题似乎是这个问题 - SDK在iPhone上缓存请求和回复。即使看起来你的NSMutableURLRequest cachePolicy被设置为不加载来自缓存的回复。

愚蠢的是,它似乎默认缓存了大量数据。我正在传输大量数据(分成多个连接)并开始收到内存警告,最后我的应用程序死了。

我们需要的文档位于NSURLCache(不是NSURLConnection)中,它们声明:

  

NSURLCache实现缓存   对URL加载请求的响应   将NSURLRequest对象映射到   NSCachedURLResponse对象。它是一个   内存和文件的复合   磁盘缓存。

     

提供了操纵方法   每个缓存的大小也是如此   至于控制磁盘上的路径使用   用于持久存储缓存数据。

这三行具有完全消除缓存的效果。将它们添加到我的应用程序(GPS Log)后,我的#living对象计数保持稳定。

答案 1 :(得分:5)

您好,您是否测试过此委托方法?

- (NSCachedURLResponse *)connection:(NSURLConnection *)connection willCacheResponse:(NSCachedURLResponse *)cachedResponse
{
    return nil;
}

您可以更精确地管理缓存。

“重置”NSURLCache * sharedCache会导致代码的其他部分出现问题吗?

答案 2 :(得分:2)

这是一个常见的问题,可以通过[object autorelease]的魔力来解决。在您的代码中,这将如下所示:

NSURLConnection *theConnection = [[[NSURLConnection alloc] initWithRequest:theRequest delegate:self] autorelease];

通过这种方式,对象会自动添加到“自动释放池”中,并在不再引用后,在下一个运行循环开始时解除分配。

希望有所帮助

编辑另外,我不明白为什么你需要在你的receivedData变量上调用-retain。

答案 3 :(得分:1)

我正在使用静态方法/自动释放的方法,它似乎工作正常:

[NSURLConnection connectionWithRequest:theRequest delegate:self];

这样您甚至不必担心在委托回调中释放。事实证明,在上面的示例中分配后,连接的保留计数实际上是2(而不是1),这改变了我对这个内存“泄漏”的看法。

@rpetrich我实际上认为你不必担心在释放连接之前释放委托。连接保留了它的委托,连接本身实际上由某种打开的连接队列保留。我在博客上写了一篇关于NSURLConnection实验的博客文章:

"Potential leak of object" with NSURLConnection