CAKeyframeAnimation - 动画图像数组在完成后创建一个巨大的分配

时间:2015-01-12 14:40:27

标签: ios objective-c xcode uiimage cakeyframeanimation

我正在尝试使用UIImageCAKeyframeAnimation数组制作动画。理论上很容易。
帖子底部的示例代码。

我的问题是,在动画完成后,我有一个巨大的泄漏,是不可能摆脱它。

初始化代码CAKeyframeAnimation

- (void)animateImages
{
    CAKeyframeAnimation *keyframeAnimation = [CAKeyframeAnimation animationWithKeyPath:@"contents"];
    keyframeAnimation.values = self.imagesArray;  // array with images

    keyframeAnimation.repeatCount = 1.0f;
    keyframeAnimation.duration = 5.0;

    keyframeAnimation.removedOnCompletion = YES;

    CALayer *layer = self.animationImageView.layer;

    [layer addAnimation:keyframeAnimation
             forKey:@"flingAnimation"];
}

向动画添加委托并手动删除动画会导致相同的泄漏效果:

... // Code to change

keyframeAnimation.delegate = self;

//    keyframeAnimation.removedOnCompletion = YES;
keyframeAnimation.removedOnCompletion = NO;
keyframeAnimation.fillMode = kCAFillModeForwards;

....

然后:

- (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag
{
    if (flag)
    {
        [self.animationImageView.layer removeAllAnimations];
        [self.animationImageView.layer removeAnimationForKey:@"flingAnimation"]; // just in case
    }
}

结果始终是一个巨大的分配。内存堆栈的大小与图像的大小成正比:

enter image description here

I uploaded an example to GitHub to check the code.

1 个答案:

答案 0 :(得分:4)

<强>解决

我发现了问题。

正如gabbler所说,没有泄漏问题。问题是图像的高分配。

我正在使用图像释放数组,但是,图像并没有从内存中消失。

所以最后我发现了问题:

    [UIImage imageNamed:@""];

从方法定义:

This method looks in the system caches for an image object with the specified name and returns that object if it exists. If a matching image object is not already in the cache, this method locates and loads the image data from disk or asset catelog, and then returns the resulting object. You can not assume that this method is thread safe.

因此,imageNamed:将图像存储在私有缓存中 - 第一个问题是您无法控制缓存大小 - 第二个问题是缓存未及时清理,如果您使用imageNamed:分配大量图像,您的应用程序可能会崩溃。

<强>解

直接从Bundle分配图像:

NSString *imageName = [NSString stringWithFormat:@"imageName.png"];
NSString *path = [[NSBundle mainBundle] pathForResource:imageName

// Allocating images with imageWithContentsOfFile makes images to do not cache.
UIImage *image = [UIImage imageWithContentsOfFile:path];

小问题

Images.xcassets中的图片永远不会被分配。因此,将图像移到Images.xcassets之外,直接从Bundle中分配。

Example project with solution here.