9

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

以及如何在 (void)ButtonClicked 中释放连接?还是稍后会发布?

- (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

4 回答 4

17

我终于找到了这个问题的答案。

上述代码中的错误(顺便说一下,这是来自SDK 文档的近乎精确的示例)不在内存管理代码中。自动释放是一种选择,手动释放是另一种选择。无论您如何处理 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 通过将 NSURLRequest 对象映射到 NSCachedURLResponse 对象来实现对 URL 加载请求的响应的缓存。它是内存和磁盘缓存的组合。

提供了一些方法来操作每个缓存的大小以及控制磁盘上的路径以用于缓存数据的持久存储。

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

于 2009-12-09T15:22:32.323 回答
5

你好,你测试过这个委托方法吗?

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

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

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

于 2011-07-24T14:32:14.597 回答
2

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

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

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

希望有帮助

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

于 2009-08-28T08:21:06.627 回答
1

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

[NSURLConnection connectionWithRequest:theRequest delegate:self];

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

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

NSURLConnection 的“潜在对象泄漏”

于 2012-01-07T06:40:23.830 回答