为什么我的应用程序似乎在内存中保存图像?

时间:2010-08-25 22:07:45

标签: objective-c iphone memory-management memory-leaks

我有一个非常大的图像的IntroViewController,它将我的应用程序的内存增加了大约1.5MB。图像在View Controller的NIB中的UIImageView上设置。

介绍完成后,我在IntroViewController上调用release,然后在其自身成功调用dealloc并在大型UIImageView上调用release。然而,我在乐器中的记忆似乎并没有再次降低。我可以通过简单地将图像重命名为NIB中的UIImageView来测试内存差异,这样它就找不到任何东西,然后内存下降大约1.5MB。

那我为什么不回忆起那段记忆呢?是否有一些我错过的东西阻止UIImageView被正确释放?

谢谢,

: - 乔

------- ADDED:CODE ------

#import <UIKit/UIKit.h>

@class AppDelegate_iPhone;

@interface IntroViewController : UIViewController
{
    AppDelegate_iPhone *appDelegate;

    UIImageView *wheelImageView;
    UIView *copyOverlayView;
}

@property (nonatomic, retain) IBOutlet UIImageView *wheelImageView;
@property (nonatomic, retain) IBOutlet UIView *copyOverlayView;

- (void)startAnimation;

@end

@implementation IntroViewController

@synthesize wheelImageView, copyOverlayView;

- (void)viewDidLoad
{
    [super viewDidLoad];
    appDelegate = (AppDelegate_iPhone *)[[UIApplication sharedApplication] delegate];
    [self startAnimation];
}

- (void)viewDidDisappear:(BOOL)animated
{
    [self.wheelImageView removeFromSuperview];
}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
}

- (void)viewDidUnload
{
    [super viewDidUnload];
    self.wheelImageView.image = nil;
    appDelegate = nil;
}

- (void)dealloc
{
     [wheelImageView release];
     [copyOverlayView release];

    [super dealloc];
}

- (void)startAnimation
{
    self.wheelImageView.transform = CGAffineTransformMakeScale(0.5, 0.5);
    [UIView beginAnimations:@"wheelScale" context:nil];
    [UIView setAnimationDuration:2.0];
    [UIView setAnimationDelegate:self];
    [UIView setAnimationDidStopSelector:@selector(wheelScaleDidFinish)];
    self.wheelImageView.transform = CGAffineTransformMakeScale(1.0, 1.0);
    [UIView commitAnimations];

    [UIView beginAnimations:@"copyOverlayFade" context:nil];
    [UIView setAnimationDuration:1.0];
    [UIView setAnimationDelay:1.0];
    self.copyOverlayView.alpha = 0;
    [UIView commitAnimations];
}

- (void)wheelScaleDidFinish
{
    [appDelegate introAnimationFinished];
}

@end

----编辑

有人可以帮忙吗?我很难过,因为内存很高,导致我的应用程序在iPhone上崩溃:(无法弄清楚如何摆脱愚蠢的形象!Grrrr ......

2 个答案:

答案 0 :(得分:1)

UIImageView正在发布,但你确定你没有在其他地方保留幻像吗?如果我是你,我会尝试追踪它的保留和释放。您可以使用时髦的调试器技巧,像malloc_history这样的工具,或者只是通过创建UIImageView的子类来实现这一点:

@interface DebugImageView @end
@implementation DebugImageView
  - (id) retain {
    NSLog(@"retained");
    return [super retain];
  }

  - (void) release {
    NSLog(@"release");
    [super release];
  }

  - (void) dealloc {
    NSLog(@"dealloc");
    [super dealloc];
  }

只需将IB中的UIImageView对象的类更改为DebugImageView,您就应该好了。您还可以在这些断点上查看它们的调用位置,或者只调用backtrace()我有记录语句的地方。

如果该对象实际上被删除,那么您的内存增加可能并不严重,并且很可能是由于一个大的可重用缓冲区对象被懒散驱逐或堆碎片。对于那种事情,1.5MB确实看起来有点高,所以我怀疑这是一个过度保留。

答案 1 :(得分:0)

好的,所以我找到了解决方案,但我对此感到非常惊讶!

我不仅需要从IB中取出UIImageView并动态创建它,我必须避免使用便捷方法来加载图像。而不是:

wheelImageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"wheel-intro.png"];
[self.view addSubview:self.wheelImageView];
[wheelImageView release];

我不得不使用:

NSString *imagePath = [[NSBundle mainBundle] pathForResource:@"wheel-intro" ofType:@"png"];
wheelImage = [[UIImage alloc] initWithContentsOfFile:imagePath];
wheelImageView = [[UIImageView alloc] initWithImage:wheelImage];
[wheelImage release];
[self.view addSubview:self.wheelImageView];
[wheelImageView release];

现在当我在[wheelImageView removeFromSuperview]处理程序中执行viewDidDisappear时,所有内容都会得到正确清理。

我发现真的很奇怪,将界面生成器中的图像放在内存管理中与在XCode中使用便捷方法相同。而且都不能正常工作!自我注意:停止使用便利方法......