iOS 完美解决CABasicAnimationDelegate强引用不释放的坑

在自定义动画的时候,我们经常用到CABasicAnimation。网上介绍CABasicAnimation怎么使用的文章已经很多了。这里就不一一介绍了。在这里主要说一下CABasicAnimation代理使用的时候需要注意的一点:代理的弱引用。

我们在使用CABasicAnimation的时候,如果直接设置动画代理,那么你这个view是不会走delloc进行释放的。Why?为什么?因为CABasicAnimation的代理强引用了动画执行的view。我们来看下系统API:

/* The delegate of the animation. This object is retained for the
 * lifetime of the animation object. Defaults to nil. See below for the
 * supported delegate methods. */

@property(nullable, strong) id  delegate;

你没有看错,苹果修饰代理的关键词使用的strong。所以执行动画的view的图层才不会走delloc。
怎么解决呢?两个方法:

0.不使用代理

这种方法有些取巧。不使用代理,既然动画是自己写的,那肯定动画时长也是知道的。直接使用

dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(<#delayInSeconds#> * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        <#code to be executed after a specified delay#>
});

执行动画完成之后的操作。但是有一个问题,万一某种原因导致动画时间改变了。逻辑就会出现问题,
不够完美(做程序就要有一颗追求完美的心)。

1.创建一个新的类,继承于CABasicAnimation,重写代理的方法

关键代码:


#import 
#import 

@protocol LEDStarAnimationDelgate

@optional
- (void)animationDidStop:(CAAnimation *)anim;

@end

@interface LEDAnimationDelegate : CABasicAnimation 

/** delegate */
@property (nonatomic,weak) id ledDelegate;

@end

·································· 我是分割线 ······························

#import "LEDAnimationDelegate.h"

@implementation LEDAnimationDelegate

- (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag{
    if ([self.ledDelegate respondsToSelector:@selector(animationDidStop:)]) {
        [self.ledDelegate animationDidStop:anim];
    }
}

- (void)setLedDelegate:(id)ledDelegate {
    _ledDelegate = ledDelegate;
    self.delegate = self;

}

- (void)dealloc {
    NSLog(@"dealloc");
}

@end

使用的时候,不要使用CABasicAnimation,使用新创建的类。如下:

LEDAnimationDelegate *opacityAnimation   = [LEDAnimationDelegate animationWithKeyPath:@"opacity"];
    opacityAnimation.fromValue               = [NSNumber numberWithFloat:1.0f];
    opacityAnimation.toValue                 = [NSNumber numberWithFloat:0.0f];
    opacityAnimation.beginTime               = CACurrentMediaTime() + self.frameTime + .7f;
    opacityAnimation.duration                = 0.01f;
    opacityAnimation.removedOnCompletion     = NO;
    opacityAnimation.fillMode                = kCAFillModeForwards;
    opacityAnimation.ledDelegate             = self;

这样就完美解决了动画代理强引用动画执行view的问题。

你可能感兴趣的:(iOS 完美解决CABasicAnimationDelegate强引用不释放的坑)