菜鸟教程小白 发表于 2022-12-13 10:02:24

ios - CAKeyframeAnimation - 对图像数组进行动画处理会在完成后创建一个巨大的分配


                                            <p><p>我正在尝试使用 <code>CAKeyframeAnimation</code> 为 <code>UIImage</code> 数组设置动画。理论上很简单。<br/>
<em>文章底部的示例代码。</em> </p>

<p>我的问题是动画完成后,我有一个无法摆脱的巨大泄漏。</p>

<p><strong>初始化代码<code>CAKeyframeAnimation</code>:</strong></p>

<pre><code>- (void)animateImages
{
    CAKeyframeAnimation *keyframeAnimation = ;
    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:@&#34;flingAnimation&#34;];
}
</code></pre>

<p>在动画中添加代理和手动移除动画会导致相同的泄漏效果:</p>

<pre><code>... // Code to change

keyframeAnimation.delegate = self;

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

....
</code></pre>

<p>然后:</p>

<pre><code>- (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag
{
    if (flag)
    {
      ;
      ; // just in case
    }
}
</code></pre>

<p>结果总是一个巨大的分配。内存堆栈的大小与图像的大小成正比:</p>

<p> <img src="/image/G0EC4.png" alt="enter image description here"/> </p>

<p> <a href="https://github.com/GabrielMassana/KeyAnimationLeak" rel="noreferrer noopener nofollow">I uploaded an example to GitHub to check the code.</a> </p></p>
                                    <br><hr><h1><strong>Best Answer-推荐答案</ strong></h1><br>
                                            <p><p><strong>已解决</strong></p>

<p>我发现了问题。 </p>

<p>作为 <a href="https://stackoverflow.com/users/4016786/gabbler" rel="noreferrer noopener nofollow">gabbler</a>是说没有泄漏问题。问题是图像的高分配。 </p>

<p>我正在释放包含图像的数组,但是图像并没有从内存中消失。</p>

<p>所以我终于找到了问题:</p>

<pre><code>    ;
</code></pre>

<p>从方法定义:</p>

<p><code>此方法在系统缓存中查找具有指定名称的图像对象,如果该对象存在,则返回该对象。如果匹配的图像对象尚未在缓存中,则此方法从磁盘或 Assets 分类日志中定位并加载图像数据,然后返回结果对象。你不能假设这个方法是线程安全的。</code></p>

<p>因此,<code>imageNamed:</code> 将图像存储在私有(private)缓存中。<br/>
- 第一个问题是你无法控制缓存大小。<br/>
- 第二个问题是缓存没有及时清理,如果你使用 <code>imageNamed:</code> 分配大量图像,你的应用程序可能会崩溃。</p>

<p><strong>解决方案</strong>:</p>

<p>直接从Bundle分配图片:</p>

<pre><code>NSString *imageName = ;
NSString *path = [ pathForResource:imageName

// Allocating images with imageWithContentsOfFile makes images to do not cache.
UIImage *image = ;
</code></pre>

<p><strong>小问题</strong>:</p>

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

<p> <a href="https://github.com/GabrielMassana/CAKeyframeAnimationExample" rel="noreferrer noopener nofollow">Example project with solution here.</a> </p></p>
                                   
                                                <p style="font-size: 20px;">关于ios - CAKeyframeAnimation - 对图像数组进行动画处理会在完成后创建一个巨大的分配,我们在Stack Overflow上找到一个类似的问题:
                                                        <a href="https://stackoverflow.com/questions/27904494/" rel="noreferrer noopener nofollow" style="color: red;">
                                                                https://stackoverflow.com/questions/27904494/
                                                        </a>
                                                </p>
                                       
页: [1]
查看完整版本: ios - CAKeyframeAnimation - 对图像数组进行动画处理会在完成后创建一个巨大的分配