在iPhone中使用NSData的内存泄漏问题

时间:2009-08-08 22:28:06

标签: iphone cocoa-touch memory-leaks

内存泄漏问题 - NSConcreteData

// to set tip - photo in photo frame    
NSData *data=[NSData dataWithContentsOfURL:[NSURL URLWithString:pathOfThumbNail]];
UIImage *cellThumbImg;
if([data length]>0){ cellThumbImg=[UIImage imageWithData:data];} else { cellThumbImg=[UIImage imageNamed:@"130X90.gif"]; }
UIImageView *imgView=[[UIImageView alloc]initWithImage:cellThumbImg]; imgView.frame=photoFrame;
(cellThumbImg.size.height>=58 || cellThumbImg.size.width>=58 ) ? [imgView setContentMode:UIViewContentModeScaleToFill] : [imgView setContentMode:UIViewContentModeCenter] ;
[cell.contentView addSubview:imgView]; 
[imgView release]; 

我的问题非常类似于这个问题,

iPhone - Memory Leak - NSData dataWithContentsOfUrl & UIWebView

即便如此,我已将以下代码添加到我的应用程序已完成启动中,如下所示。 以下代码用于设置零容量的sharedCache内存。它几乎会删除我的应用程序中的NSConcreteData泄漏。但内存泄漏。

- (void)applicationDidFinishLaunching:(UIApplication *)application {       
NSURLCache *sharedCache = [[NSURLCache alloc] initWithMemoryCapacity:0 diskCapacity:0 diskPath:nil];
[NSURLCache setSharedURLCache:sharedCache];
[sharedCache release];
[window makeKeyAndVisible];
}

我无法从堆栈溢出中找到任何解决此类问题的方法。

如果你能回答,我会感谢你。

提前致谢。

4 个答案:

答案 0 :(得分:10)

你有三行,让我们分解

1. NSData *imageData = [[NSData alloc] init];
2. imageData = [NSData dataWithContentsOfURL:[NSURL URLWithString:@"www.xyz.abc.com"]];
3. [imageData release];

第1行:分配并初始化一个新的NSData。此NSData的引用计数为+1

第2行:从互联网获取数据并放入NSData。这将使用第1行的变量设置为新的NSData(设置为自动释放),隐藏在第1行分配和引入的NSData

第3行:将释放第2行收到的NSData。

你可以删除第1行和第3行,只需将变量声明添加到第2行。由于它是自动释放的,它将在以后的eventloop中释放...

NSData *imageData = [NSData dataWithContentsOfURL:[NSURL URLWithString:@"www.xyz.abc.com"]];

我建议您阅读内存管理部分here

答案 1 :(得分:7)

我的大型项目也存在问题。在与Apple工程师一起试图找到漏洞后,他终于向NSURLConnection背后的主要Apple开发团队询问了问题。他们基本上说在NSURLConnection中有一个内部缓存根本无法清除,这是一个已知的问题。

所以我开始寻找替代方案。我发现了ASIHTTPConnection(链接如下),它起作用于CFNetwork。它被设计成NSURLConnection的直接替代品,加上一堆其他令人敬畏的好东西,比如下载到磁盘而不是内存,下载恢复,进度条回调等等。

我在所有项目中都使用过它,从未遇到任何问题或投诉。答:回答你的问题,这就是我如何摆脱那些内存泄漏。

http://allseeing-i.com/ASIHTTPRequest/

答案 2 :(得分:7)

每当我们使用dataWithContentOfURL时,我们都必须使用NSAutoReleasePool将其括起来,如下所示:

NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];

// ** Your Operations **

NSData *data = [NSData dataWithContentsOfURL:someURL];

// ** Your Operation **

[data autorelease];
[pool release];

这甚至适用于NSURLRequestNSURLConnection

问题在于编译器本身,以上是解决问题的唯一方法。

答案 3 :(得分:4)

您的发布消息拼写错误,您输入了relaese,但它是release。我认为这只是你为这个问题键入的代码中的一个问题。

二。您不需要第一个alloc init链消息。您所需要的只是:

NSData *imageData = [NSData dataWithContentsOfURL:[NSURL URLWithString:@"www.xyz.abc.com"]];

当然,我不知道该调用是否确实正确,但我知道它会返回一个自动释放的NSData对象,这意味着您之前的alloc init会泄漏。