Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/objective-c/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Objective c 连接泄漏?_Objective C_Memory Management_Memory Leaks_Nsurlconnection_Nsurlrequest - Fatal编程技术网

Objective c 连接泄漏?

Objective c 连接泄漏?,objective-c,memory-management,memory-leaks,nsurlconnection,nsurlrequest,Objective C,Memory Management,Memory Leaks,Nsurlconnection,Nsurlrequest,我已经建立了一个nsurl,它从http获取数据。 当我运行仪器时,它说我有一个泄漏NSFNetwork对象 如何释放选中的(无效)按钮中的连接?或者稍后会发布 - (void)ButtonClicked { NSURLRequest *theRequest = [NSURLRequest requestWithURL:[NSURL URLWithString:KmlUrl] cachePol

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

如何释放选中的(无效)按钮中的连接?或者稍后会发布

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

}

这是一个常见的问题,通过[对象自动释放]的魔力可以解决。在您的代码中,这将如下所示:

NSURLConnection *theConnection = [[[NSURLConnection alloc] initWithRequest:theRequest delegate:self] autorelease];
通过这种方式,对象将自动添加到“自动释放池”中,并在不再引用该对象后在下一次运行循环开始时解除锁定

希望有帮助


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

我终于找到了答案

上述代码中的错误(顺便说一句,这是来自的接近精确的示例)不在内存管理代码中。自动释放是一种选择,手动释放是另一种选择。无论如何处理NSURLConnection对象,使用NSURLConnection都会导致泄漏

首先,这里是解决方案。只需将这3行代码直接复制到ConnectionIDFinishLoading、didFailWithError和释放NSURLConnection对象的任何其他地方

NSURLCache *sharedCache = [[NSURLCache alloc] initWithMemoryCapacity:0 diskCapacity:0 diskPath:nil];
[NSURLCache setSharedURLCache:sharedCache];
[sharedCache release];
该代码归功于mpramodjain

问题似乎是这样的——SDK将请求和回复缓存在iPhone上。即使您的NSMutableURLRequest cachePolicy设置为不从缓存加载回复,也会出现这种情况

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

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

NSURLCache实现了 对URL加载请求的响应 将NSURLRequest对象映射到 nsCachedUrResponse对象。这是一个 由内存中的和 在磁盘缓存上

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


这三条线的作用是完全破坏缓存。将它们添加到我的应用程序()后,我的活体计数保持稳定。

您好,您测试过此委托方法吗

- (NSCachedURLResponse *)connection:(NSURLConnection *)connection willCacheResponse:(NSCachedURLResponse *)cachedResponse
{
    return nil;
}
您可以更精确地管理缓存


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

我使用的是静态方法/自动重置方法,它似乎工作正常:

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

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


调用autorelease将起作用,但在释放连接之前释放委托的情况下,调用autorelease将失败。更好的方法是将连接分配给实例变量,并在不需要时释放+nil。如果在对象解除分配时仍分配了连接ivar,则需要在释放连接之前将委托设置为nil。@rpetrich我同意您的建议更全面,然而,很明显,他的问题显示了对iPhone内存管理的基本误解,因此我想给他一个概念上更简单的解释solution@rpetrich,你能提供一个代码示例吗。我已经用很多方法解决了这个问题,但仍然存在漏洞。@rpetrich,是的,我也想看看你的例子。为了记录在案,我切换到了autorelease'd[NSURLConnectionWithRequest:request delegate:self],但我认为这不重要。如果你的应用程序发出任何其他NSURLConnection请求,应该使用缓存,此解决方案将禁用它们。在这种情况下,更好的解决方案可能是实现缓存响应委托(具有相同的效果):
-(NSCachedURLResponse*)连接:(NSURLConnection*)连接将缓存响应:(NSCachedURLResponse*)缓存响应{return nil;}
进一步了解实际发生的情况:NSURLCache正在缓存对请求的响应,但它使用请求作为密钥。因此,只要缓存响应,它就会保留请求。一个0字节的缓存会破坏这一点,代价是让应用程序发出的所有请求都不缓存;实现委托方法是一种更为定制的方法。将请求的缓存策略设置为忽略缓存是不够的。如果您不想完全禁用缓存,并且不能或不想使用与委托的异步连接,则可以调用
[[NSURLCache sharedullcache]removeCachedResponseForRequest:request]发送请求后,我正在使用+[NSURLConnection sendAsynchronousRequest:queue:completionHandler:]和+[NSURLConnection sendSynchronousRequest:returningResponse:error]以及您设置缓存的方法,但是,仅在这些方法上,活动字节不断增加,最终我的应用程序在>30 Mb后被杀死。你知道吗?对于sendSynchronousRequest,我使用串行队列在dispatch\u async中执行此操作。谢谢