【问题标题】:Removing CAKeyframeAnimation doesn't release the memory删除 CAKeyframeAnimation 不会释放内存
【发布时间】:2012-01-26 16:58:49
【问题描述】:

我在 ImageView 的层中添加了一个 CAKeyframeAnimation 来表示图像的动画:

CAKeyframeAnimation *animation = [CAKeyframeAnimation animationWithKeyPath:@"contents"];
animation.values = arrayOfImages;
[animation setRemovedOnCompletion:YES];
animation.delegate = self;
[animation setValue:delegate forKey:@"AnimatedImageViewDelegate"];
animation.repeatCount = repeatCount;
animation.fillMode = kCAFillModeForwards;
animation.calculationMode = kCAAnimationDiscrete;
[animation setValue:animationName forKey:@"name"];

当我想开始我调用的动画时:

animation.duration = duration;
[self.layer addAnimation:animation forKey:animationName];
[self.layer setContents:[animation.values lastObject]];

当动画完成后,我想将它完全移除并释放它的内存。

[self.layer removeAllAnimations];       
[self.layer removeAnimationForKey:animationName];

这样做并使用 Instruments-Activity Monitor,除非我释放完整的 imageView,否则不会释放内存。

如何在不破坏 UIImageView 的情况下释放动画内存???

【问题讨论】:

  • 你可以试试把它放到autoreleasepool中

标签: iphone cocoa-touch uiimageview core-animation cakeyframeanimation


【解决方案1】:

您正在使用便捷方法来实例化对象。因此,您将无法控制对象实际释放的时间。要控制它,您需要自己分配对象并解除分配:

创建实例:

CAKeyframeAnimation *animation = [[CAKeyframeAnimation alloc] init];

然后在你的删除线之后动画完成调用:

[animation release];

【讨论】:

  • [CAKeyframeAnimation animationWithKeyPath:] 返回一个自动释放的对象(根据命名约定)并且他似乎没有保留它(至少他没有在他提供的代码中这样做)所以他应该没问题。这样做 alloc/release 不会改变这一点。事实上,从他的代码来看,我想说一切都很好,所以问题一定出在其他地方。
  • 是的,除了自动释放时他无法控制释放。听起来它在视图被销毁时会自动释放,所以看起来至少值得一试。
  • 即使做动画分配/初始化和释放,当我使用活动监视器时内存并没有减少。因此,使用自动释放或释放在内存方面没有区别。如果我评论这条线 animation.values = arrayOfImages;动画没有显示并且内存没有增加,所以我的问题是当动画完成时内存根本不会释放,除非我释放 ImageView。
【解决方案2】:

首先,如果这是一个 iOS 5 项目,ARC 应该会为您处理您的版本 - 这真的很棒!

现在——我在我的项目中使用了很多动画,并注意到堆中有类似的爆发。我的猜测是 CA 缓存了很多内部动画。为了确认这些项目实际上是自动释放的,我建议使用工具工具设置分配或泄漏测试并执行以下操作:

  1. 确定要触发的情况和动画。
  2. 在动画完成后标记堆。
  3. 触发一些东西,将您带到另一个应该删除对象的视图。
  4. 根据需要多次重复步骤 1-2-3 中的过程。我通常会做 10 次左右。

就是这样......基本上是动画 - 标记 - 撤消 - 动画 - 标记。如果 CoreAnimation 正确地自动释放对象,您应该会看到 heapshots 减少到 0 或几乎为 0!

有关如何进行这样的测试的更多信息,请查看这篇文章:

http://www.friday.com/bbum/2010/10/17/when-is-a-leak-not-a-leak-using-heapshot-analysis-to-find-undesirable-memory-growth/

【讨论】:

  • 感谢您的回答。一旦动画完成,它就会减少到几乎为 0,但前提是我释放 ImageView。在不释放它的情况下,堆增长非常高(每次从 40KB 到 800KB)。这意味着 CoreAnimation 在完成时不会释放。
【解决方案3】:

当设置值 = 图像数组时,我对 CAKeyframeAnimation 的内存有同样的问题。 我看到我得到的问题是图像是由 [UIImage imagewithname:] 初始化的,默认情况下它被缓存到内存中。所以我的解决方案是更改为使用 [UIImage imageWithContentsOfFile:] 希望这会有所帮助。

【讨论】:

    【解决方案4】:

    在我的情况下,添加到 imageView 和容器视图的 CAKeyframeAnimation 没有被释放,即使它不在视图层次结构中。

    原来是 CAKeyframeAnimation 委托持有它。我刚刚删除了委托:

    beatAnimation.delegate = nil
    

    【讨论】:

      猜你喜欢
      • 2013-06-05
      • 2013-01-10
      • 1970-01-01
      • 2017-03-01
      • 1970-01-01
      • 2014-11-17
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多