首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >NSImage内存泄漏

NSImage内存泄漏
EN

Stack Overflow用户
提问于 2014-07-05 13:39:50
回答 3查看 1K关注 0票数 0

首先:我已经在谷歌上搜索过了,所以我想找到解决方案--都没有用。我有一个应用程序,它加载当前iTunes跟踪的艺术品并显示它;它存储在一个NSImage实例中,以及其他一些变量中,存储在一个类中:

代码语言:javascript
复制
@interface infoBundle : NSObject
 @property (strong) NSImage *track_artwork;
 @property (weak) NSString *track_title;
 @property (weak) NSString *track_album;
 @property (weak) NSString *track_artist;
@end

然后,创建该类的实例:

代码语言:javascript
复制
-(infoBundle*)returnInfoBundle {
 infoBundle* tmpBundle = [[infoBundle alloc]init];
 tmpBundle.track_artwork = [[NSImage alloc]initWithData:[(iTunesArtwork *)[[[iTunes currentTrack] artworks] objectAtIndex:0] rawData]];
 [...]
 return tmpBundle;
}

后来又使用:

代码语言:javascript
复制
-(void)iTunesDidChange {
 infoBundle* tmpBundle = [self returnInfoBundle];
 [...]
 [imageView setImage:tmpBundle.track_artwork];
}

这将占用iTunesDidChange的每个调用2MB(我猜是覆盖大小)。

我已经试过了

  • tmpBundle自释放;
  • tmpBundle释放;
  • tmpBundle dealloc;
  • tmpBundle =0;

在那之后就没用了:-启用ARC。

=>为什么会消耗内存,尽管应该删除对象(tmpbundle)?=>如何实现无泄漏的NSImage使用?

谢谢您的提示/建议/解决方案:)

EN

回答 3

Stack Overflow用户

发布于 2014-07-05 22:14:41

问题

如果在方法上创建对象,而不是在该方法中释放对象,则会出现内存泄漏,或者在通过引用将对象作为参数传递时必须引用它:Passing arguments by value or by reference in objective C

您的问题是,您正在创建一个infoBundle实例两次,当您初始化它的另一个实例时,您将第一个实例保留在没有引用的情况下,因此它仍然留在内存中,并且没有连接来删除它(内存泄漏)。

解决方案

为了简化您的工作,您应该创建对象的一个实例。

代码语言:javascript
复制
@implementation
{
    infoBundle* tmpBundle;
}

在你需要它的任何地方都可以使用它

代码语言:javascript
复制
-(infoBundle*)returnInfoBundle 
{
    tmpBundle = [[infoBundle alloc]init];
    tmpBundle.track_artwork = [[NSImage alloc]initWithData:[(iTunesArtwork *)[[[iTunes currentTrack] artworks] objectAtIndex:0] rawData]];
    [...]
    return tmpBundle;
}

-(void)iTunesDidChange 
{
    tmpBundle = [self returnInfoBundle];
    [...]
    [imageView setImage:tmpBundle.track_artwork];
} 

当您完成该对象时,dealloc将自动释放它,如果您将它添加到dealloc方法中:

代码语言:javascript
复制
- (void) dealloc
{
    [tmpBundle release];
    tmpBundle = nil;
}

希望能有所帮助!)

票数 0
EN

Stack Overflow用户

发布于 2014-07-06 11:04:00

只需修改这一行:-

代码语言:javascript
复制
  infoBundle* tmpBundle = [[[infoBundle alloc]init]autorelease];
票数 0
EN

Stack Overflow用户

发布于 2014-07-05 14:15:33

我无法从您的代码中看出您在imageView setImage:tmpbundle.track_artwork中正在做什么;但是您可能遇到了与我相同的问题。

我在用

代码语言:javascript
复制
self.imageToDisplay  = [UIImage imageNamed:pictFileName];

一直在泄密。我转到

代码语言:javascript
复制
self.imageToDisplay = [UIImage imageWithContentsOfFile:pictFile];

然后他们就走了。

根据imageNamed的文档,

此方法在系统缓存中查找具有指定名称的图像对象,如果存在…,则返回该对象。如果您的图像文件只显示一次,并且希望确保它不会被添加到系统的缓存中,则应该使用imageWithContentsOfFile:创建映像。这将使您的单用途映像远离系统映像缓存,从而可能改善应用程序的内存使用特性。

听起来你要么有同样的问题,要么有类似的问题。

票数 -1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/24586991

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档