【问题标题】:Strange releasing problem奇怪的释放问题
【发布时间】:2011-05-09 21:14:10
【问题描述】:

我有一个奇怪的问题,但我很确定,对你来说不是。如果是这样,请帮助我或解释。 我有一个包含 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];

【问题讨论】:

  • -1 因为您的代码又一次完全不起作用了。它会立即崩溃,因为您过度释放 path。显示实际代码。编辑:好的,它不会直接崩溃,但它在图像释放时崩溃。
  • 我怎样才能把整个项目发给你?最有趣的是,没有任何崩溃。
  • 当然它不会崩溃,因为你的图片没有发布 - 因此你的问题。
  • releasing problems 的可能重复项
  • 如果添加 39 张图片,您可能希望从至少 39 张容量开始。

标签: iphone objective-c memory-management


【解决方案1】:

我认为您需要从数组中删除所有对象才能使其工作。

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

【讨论】:

  • 试图数组=nil;图像视图=无;但什么也没发生。分配的内存仍然是 23 MB。有什么想法吗?
【解决方案2】:

您正在释放imageView 而不在任何地方保留它,因此您的代码可能还有其他问题。然而,imageView 似乎被另一个对象(很可能是超级视图)保留,它将它保存在内存中。这也会将图像数组保存在内存中。

如果您不再需要 imageView,请使用 [imageView removeFromSuperview]; 将其从其父级中删除

【讨论】:

  • imageView 是用 IB 创建的。在 dealloc 中合成并释放。仍然没有改善。如果您有空闲时间并愿意提供帮助,我可以通过电子邮件将此代码发送给您。
  • 我明白了,但是你也在 viewDidLoad 中释放它,所以你的 dealloc 可能会崩溃!如果您只想释放内存,动画停止后的imageView.animationImages = nil; 可能会有所帮助。
  • dealloc 不会崩溃。并且没有在 viewDidLoad 中释放相同的结果。也许我错了 - 删除 imageView 和数组后,内存会被释放吗?是不是?试过 imageView.animationImages = nil ,结果还是一样。
【解决方案3】:

我们已经在这里解决了:releasing problems

设置imageView.animationImages = nil;

另外,您需要删除[path release];,否则它会崩溃。

Memory Management Guide 是一个重要的起点。

编辑 从不依赖retainCount属性!

Edit 2 在那个方法中释放 imageView 显然也是一个 bug!

【讨论】:

  • 我已阅读并按照我认为的正确方式做的指南。奇怪,但是没有什么会随着 [path release] 而崩溃;好的。但是为什么 Allocations Instrument 显示我还有 24mb 空间被使用?
  • 伙计,你插入了 imageView.animationImages = nil;你玩Animation2吗?
  • 是的,它在那里,但我不知道发生了什么,但在删除所有之后它现在可以工作了!谢谢
【解决方案4】:

这段代码有很多问题。它运行起来真是个奇迹。

第一:

不要使用 -retainCount。

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

您应该调用release 的次数与您导致对象被保留的次数完全相同。不会少(除非您喜欢泄漏),当然也不会更多(除非您喜欢崩溃)。

详情请参阅Memory Management Guidelines


现在,一些问题:

  • 你问是否需要清空数组,然后说array=nil; ... 不起作用。将数组引用设置为 nil 不会对数组做任何事情;不会释放或清空它。

  • 你过度释放path

  • 您正在加载一系列图像,将它们粘贴在一个数组中,并且该代码中没有任何内容会释放数组(或清空它)。您的应用继续使用内存并且没有泄漏,这听起来像是正确的行为。

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

【讨论】:

  • +1 你知道,我可以发誓我以前见过这个完全相同的答案... ;)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-09-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-11-08
相关资源
最近更新 更多