5

I'm adding a CAKeyframeAnimation to the layer of an ImageView for representing the animation of an image:

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"];

When I want to start the animation I call:

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

When the animation finishes, I want to completely remove it and release its memory.

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

Doing this, and using Instruments-Activity Monitor, the memory is not relased unless I release the complete imageView.

How can I release that animation memory without destroy the UIImageView???

nano
  • 2,511
  • 4
  • 25
  • 42

4 Answers4

0

I have same problem about memory with CAKeyframeAnimation when set values = array of images. And i see that the problem i get is that the images are inited by [UIImage imagewithname:] which is cached to memory by default. So my solution is change to use [UIImage imageWithContentsOfFile:] Hope this helpful.

Đông Hà
  • 222
  • 3
  • 16
0

In my case the CAKeyframeAnimation added to an imageView and container view is not getting released even that its not on the view hierarchy.

It turned out that the CAKeyframeAnimation delegate was holding it. I just removed the delegate:

beatAnimation.delegate = nil
hasan
  • 23,815
  • 10
  • 63
  • 101
0

You are using the convenience method to instantiate the object. So you will not have control over when the object is actually released. To have control over that, you will need to alloc the object and dealloc it yourself:

Create the instance:

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

Then after the animation finished call after your remove lines:

[animation release];
Jeshua Lacock
  • 5,730
  • 1
  • 28
  • 58
  • `[CAKeyframeAnimation animationWithKeyPath:]` returns an autoreleased object (as per the naming convention) and he doesn't seem to retain it (at least he's not doing it in the code he's presented) so he should be fine. Doing `alloc/release` instead won't change that. Indeed, from his code I'd say everything is absolutely fine so the issue must be elsewhere. – DarkDust Jan 27 '12 at 07:27
  • True, except, he has no control when it is released when it is autoreleased. It sounds like it is being autoreleased when the view is destroyed, so seems like at least something worth trying. – Jeshua Lacock Jan 27 '12 at 08:12
  • Even doing the animation alloc/init and release, the memory is not decreasing when I use Activity Monitor. So, no difference in terms of memory using autorelease or release. If I comment the line animation.values = arrayOfImages; the animation is not being showed and the memory doesn't increase, so my problem is that when the animation finishes the memory is not released at all unless I release the ImageView. – nano Jan 27 '12 at 10:29
0

First off, if this is an iOS 5 project ARC should be handling your releases for you - which is really nice!

Now -- I used a lot of animations in my project and noticed similar bursts in the heap. My guess is that CA caches a lot of what is animated internally. To confirm those items are actually being autoreleased I recommend setting up a test for allocations or leaks with the instruments tool and do the following:

  1. Determine a situation where you would trigger and the animation.
  2. Mark the heap after the animation completes.
  3. Trigger something that would take you to another view where the objects should have been removed.
  4. Repeat the process in steps 1-2-3 as many times as you want. I normally do it about 10 times or so.

That's it.. basically animate - mark - undo - animate - mark. You should see the heapshots decreasing to 0 or almost 0 if CoreAnimation is autoreleasing objects correctly!

For more info on how to test like this take a look at this article:

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

Jim Jeffers
  • 17,572
  • 4
  • 41
  • 49
  • Thanks for your answer. It decreases to almost 0 once the animation finishes but only if I release the ImageView. Without releasing it, the heap growths are quite high (from 40KB till 800KB each time). That means CoreAnimation is not releasing when it finishes. – nano Feb 15 '12 at 10:32