我已经设置了一个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];
}
答案 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实验的博客文章: