在自定义动画的时候,我们经常用到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 <CAAnimationDelegate> 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 <Foundation/Foundation.h>
#import <QuartzCore/QuartzCore.h>
@protocol LEDStarAnimationDelgate<NSObject>
@optional
- (void)animationDidStop:(CAAnimation *)anim;
@end
@interface LEDAnimationDelegate : CABasicAnimation <CAAnimationDelegate>
/** delegate */
@property (nonatomic,weak) id<LEDStarAnimationDelgate> 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<LEDStarAnimationDelgate>)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的问题。