I have seen How to identify CAAnimation within the animationDidStop delegate?, this is an addition to it.
I'm unable to get this working properly. I have an animation, and I'd like to release the controller that it was run in after the end of the animation. Example: The controller translates from right -> left then releases itself.
Defining the animation:
NSValue *end = [NSValue valueWithCGPoint:CGPointMake(800, self.view.center.y)];
NSValue *start = [NSValue valueWithCGPoint:self.view.center];
CABasicAnimation *moveAnimation;
moveAnimation = [CABasicAnimation animationWithKeyPath:@"position"];
moveAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
moveAnimation.duration = 0.45f;
moveAnimation.fromValue = start;
moveAnimation.toValue = end;
// actually set the position
[self.view.layer setPosition:[end CGPointValue]];
moveAnimation.delegate = self;
moveAnimation.removedOnCompletion = NO;
[self.view.layer addAnimation:moveAnimation forKey:MOVING_OUT];
Inside the delegate method:
- (void) animationDidStop:(CAAnimation *)theAnimation finished:(BOOL)flag
{
CAAnimation *check = [self.view.layer animationForKey:MOVING_OUT];
if (theAnimation == check)
{
//[check release];
[self release];
}
}
If I leave this code as-i开发者_如何转开发s, my controller doesn't get dealloc'd (due to the retain call by the animation).
If I run [check release]
, I get the message sent to deallocated instance
.
Does anyone know what's wrong?
Is there another way to identify a CAAnimation in the animationDidStop
delegate WITHOUT specifying removedOnCompletion = NO
?
EDIT:
Forgot to mention. By not specifying that removedOnCompletion = NO
, animationForKey:
will return NULL. Hence I'm unable to identify the animation.
Thanks!
I think the eventual reason is CAAnimation.delegate is a retain property (very strange oops!).
The header file definition is:
/* 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(retain) id delegate;
To let self get release, the animation must be removed from layer, like:
[self.view.layer removeAnimationForKey:@THE_ANIMATION_KEY];
It's not clear what your problem is here, but it may help you to know that CAAnimation
instances are generic KVO containers, so you can add custom info to them:
[myAnimation setValue: @"check" forKey: @"name"];
You can then check against that:
if ([[theAnimation valueForKey: @"name"] isEqual: @"check"])
// ...
Does that help?
精彩评论