【问题标题】:memory leak problem using NSData in iPhone在 iPhone 中使用 NSData 的内存泄漏问题
【发布时间】:2010-11-18 00:21:03
【问题描述】:

内存泄漏问题 - 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];
}

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

如果你能回答,我会很感激你。

提前致谢。

【问题讨论】:

标签: iphone cocoa-touch memory-leaks


【解决方案1】:

你有三行,让我们分解一下

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

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

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

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

您可以删除第 1 行和第 3 行,只需将变量声明添加到第 2 行。因为它是自动释放的,所以稍后将由 eventloop 释放...

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

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

【讨论】:

  • @ePatel - 先生,请查看我的问题中的更正。我有同样的问题。即使在应用您建议的逻辑之后,我也发现了相同的内存泄漏问题。
  • Nit:第 2 行隐藏刚刚分配/初始化的 imageData,创建一个新的。
  • 我显然是个白痴,对不起。我在你的 cmets 中寻找过,但错过了,并根据编辑后的问题做了一个糟糕的假设......
【解决方案2】:

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

所以我开始寻找替代方案。我发现 ASIHTTPConnection(下面的链接)可以在 CFNetwork 之外工作。它旨在成为 NSURLConnection 的直接替代品,以及许多其他很棒的功能,例如下载到磁盘而不是内存、下载恢复、进度条回调等。

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

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

【讨论】:

  • 虽然这是公认的答案并且可能解决了 OP 的问题,但我忽略了 epatel 答案中更简单的解决方案。他的答案应该是被接受的。
【解决方案3】:

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

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

// ** Your Operations **

NSData *data = [NSData dataWithContentsOfURL:someURL];

// ** Your Operation **

[data autorelease];
[pool release];

这甚至适用于NSURLRequestNSURLConnection

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

【讨论】:

  • 这绝对是错误的。您没有使用 retainalloccopymutableCopynew 中的任何一个保留对象。你无权autorelease它。这是不正确的,会导致你的程序在某个地方失败。
【解决方案4】:

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

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

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

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

【讨论】:

  • @Blaenk - 先生,请查看我的问题中的更正。我有同样的问题。即使在应用您建议的逻辑之后,我也发现了相同的内存泄漏问题。
猜你喜欢
  • 2010-09-21
  • 2011-11-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多