奇怪的释放问题

问题描述:

我有一个奇怪的问题,但我很确定,对你来说不是这样。如果是这样,请帮我解释一下。 我有一个39 UIImages数组将用于动画UIImageView。并在播放动画后,内存不会释放。奇怪的释放问题

- (void)viewDidLoad { 
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc]init]; 
    NSMutableArray* actionArray = [[NSMutableArray alloc]initWithCapacity:38]; 

    for (int i=1; i<=39; i++) { 
     NSString* path = [[NSBundle mainBundle]pathForResource:[NSString stringWithFormat:@"bg_Level1_%.4d", i] ofType:@"png"]; 
     UIImage *image = [[UIImage alloc]initWithContentsOfFile:path]; 
     [path release]; 
     [actionArray addObject:image]; 
     [image release]; 
     NSLog(@"path rc %d image %d", [path retainCount], [image retainCount]); 
    } 
    imageView.animationImages = actionArray; 
    imageView.animationDuration = 4.0; 
    imageView.animationRepeatCount = 1; 
    [imageView startAnimating]; 
    NSLog(@"RetainCount ActArr %d ImageView %d", [actionArray retainCount], [imageView retainCount]); 
    [actionArray release]; 
    [pool drain]; 
    [imageView release]; 
    [self performSelector:@selector(playAnimation2) withObject:self afterDelay:5.0]; 
    [super viewDidLoad]; 
} 

-(void)playAnimation2{ 
    if ([imageView isAnimating]) { 
     [imageView stopAnimating]; 
    } 
    NSLog(@"RetainCount ImageView %d",[imageView retainCount]); 
} 

没有发现泄漏,但分配的内存量仍然是24 MB。

或者它不是那么必要?

编辑:

对不起,我的错。 由于我的代码有很多变化,我迷失了它。分析后,我明白了! 非常感谢!

正确的代码是:

- (void)viewDidLoad { 
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc]init]; 
    NSMutableArray* actionArray = [[NSMutableArray alloc]initWithCapacity:38]; 

    for (int i=1; i<=39; i++) { 
     NSString* path = [[NSBundle mainBundle]pathForResource:[NSString stringWithFormat:@"bg_Level1_%.4d", i] ofType:@"png"]; 
     UIImage *image = [[UIImage alloc]initWithContentsOfFile:path]; 
//  [path release]; 
     [actionArray addObject:image]; 
     [image release]; 
     NSLog(@"path rc %d image %d", [path retainCount], [image retainCount]); 
    } 
    imageView.animationImages = actionArray; 
    imageView.animationDuration = 4.0; 
    imageView.animationRepeatCount = 1; 
    [imageView startAnimating]; 
    NSLog(@"RetainCount ActArr %d ImageView %d", [actionArray retainCount], [imageView retainCount]); 
    [actionArray release]; 
    [pool drain]; 
    [self performSelector:@selector(playAnimation2) withObject:self afterDelay:5.0]; 
    [super viewDidLoad]; 
} 

-(void)playAnimation2{ 
    if ([imageView isAnimating]) { 
     [imageView stopAnimating]; 
    } 
    [imageView removeFromSuperview]; 
    imageView.animationImages = nil; 
    NSLog(@"RetainCount ImageView %d",[imageView retainCount]); 
} 

的问题是与[path release];

+0

-1因为您的代码再一次根本不工作。它会立即崩溃,因为您正在释放* path *。显示实际的代码。编辑:好吧,它不会直接崩溃,但它会*图像发布时崩溃。 – Eiko 2010-11-14 17:59:08

+0

我怎样才能给你整个项目?最有趣的是,没有任何崩溃。 – 0xDE4E15B 2010-11-14 18:04:47

+0

当然,它不会崩溃,因为你的图像不会释放 - 因此你的问题。 – Eiko 2010-11-14 18:05:29

这段代码有很多错误。这完全是一个奇迹。

第一张:

请勿使用-retainCount。

对象的绝对保留数是没有意义的。

您应该致电release完全相同的次数导致对象被保留。没有更少(除非你喜欢泄漏),当然,没有更多(除非你喜欢崩溃)。

查看Memory Management Guidelines的全部细节。


现在,一些问题:

  • 你问,如果你需要清空数组,然后说:阵列=零; ...不起作用。将数组引用设置为nil不会对数组执行任何操作;不释放它或清空它。

  • 你overreleasing path

  • 您加载了一系列图像,坚持“时间在阵列中,并没有在该代码被释放阵列(或排空)任何东西。您的应用程序会继续使用内存,并显示没有泄漏听起来像正确的行为。

  • 你为什么要发布imageView?代码中没有任何内容暗示你保留了它,即使它是通过其他机制(IB?)保留的,那将是一个非常奇怪的发布它的地方。

+0

+1你知道,我可以发誓我以前见过这个完全相同的答案...;) – 2010-11-14 18:50:11

我认为你需要从数组中删除的所有对象为它工作。

尝试从数组中删除对象,然后尝试从数组中删除对象。

+0

试图array = nil;的ImageView =无;但没有任何反应。分配的内存仍然是23 MB。有任何想法吗? – 0xDE4E15B 2010-11-14 17:42:30

你正在发布imageView而没有保留在任何地方,所以你的代码可能有其他错误。但似乎imageView被另一个对象(最有可能的是超级视图)保留,它保留在内存中。这也将保持图像阵列在内存中。

如果您不需要再imageView从父与[imageView removeFromSuperview];

+0

imageView是使用IB创建的。合成并在dealloc中发布。仍然没有改善。如果您有空闲时间并希望帮助,我可以通过电子邮件向您发送此代码。 – 0xDE4E15B 2010-11-14 17:50:54

+0

我明白,但你也在viewDidLoad这里发布它,所以你的dealloc可能会崩溃!如果你只是想释放内存,动画停止后的'imageView.animationImages = nil;'可能会有所帮助。 – FRotthowe 2010-11-14 17:54:24

+0

dealloc不会崩溃。并且不会在viewDidLoad中释放相同的结果。也许我错了 - 删除imageView和数组后,内存将被释放?是不是?尝试imageView.animationImages =零,同样的结果仍然存在。 – 0xDE4E15B 2010-11-14 17:58:54

删除它正如我们已经在这里解决:releasing problems

imageView.animationImages = nil;

此外,你需要删除[path release];或它会崩溃。

Memory Management Guide是一个重要的开始。

编辑从来没有依赖于retainCount属性!

编辑2在该方法中释放imageView显然也是一个错误!

+0

我读过的指南和我正在做的,正如我认为的,以正确的方式。奇怪,但没有与[路径释放]崩溃;好的。但为什么Allocations Instrument显示我仍然有24mb使用? – 0xDE4E15B 2010-11-14 18:09:45

+0

男人,你插入imageView.animationImages = nil;给你玩动画2? – Eiko 2010-11-14 18:11:28

+0

是的,它在那里,但我不知道发生了什么,但现在删除后,它的作品!谢谢 – 0xDE4E15B 2010-11-14 18:15:45