开发者

How to identify CAAnimation in delegate and release controller?

开发者 https://www.devze.com 2023-01-30 13:24 出处:网络
I have seen How to identify CAAnimation within the animationDidStop delegate?, this is an addition to it.

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?

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号