Question

I have a method that performs a simple animation then calls itself again. The problem is that the UIViewController is never dealloc'd, I assume because of the continuous run loop.

If I comment out the line that recalls the animation method, it gets dealloc'd fine.

I have tried using performSelector to loop the animation, but calling [NSOperation cancelPreviousPerformRequestsWithTarget:self]; in viewWillDisappear doesn't seem to cancel it. Possibly because i'm using afterDelay:0.0?

Here is my animation method:

- (void)animateArrows
{
    UIImage *toImage;
    switch (animState) {
        case ARROWS:
            toImage = arrow_1;
            animState++;
            break;

        case ARROW_1:
            toImage = arrows;
            animState++;
            break;

        case ARROWS_1:
            toImage = arrow_2;
            animState++;
            break;

        case ARROW_2:
            toImage = arrows;
            animState++;
            break;

        case ARROWS_2:
            toImage = arrow_3;
            animState++;
            break;

        case ARROW_3:
            toImage = arrows;
            animState = ARROWS;
            break;

        default:
            break;
    }

    [UIView transitionWithView:self.sendButton
                      duration:0.6f
                       options:UIViewAnimationOptionTransitionCrossDissolve | UIViewAnimationOptionAllowUserInteraction
                    animations:^{
                        [self.sendButton setImage:toImage forState:UIControlStateNormal];
                    } completion:^(BOOL finished){

                        [self performSelector:@selector(animateArrows) withObject:nil afterDelay:0.0];
//                        [self animateArrows];
                    }];
}
Was it helpful?

Solution

All you need to do is add a BOOL property that indicates whether or not the animation should keep looping. Then change that animation block to something like:

[UIView transitionWithView:self.sendButton
                  duration:0.6f
                   options:UIViewAnimationOptionTransitionCrossDissolve | UIViewAnimationOptionAllowUserInteraction
                animations:^{
                    [self.sendButton setImage:toImage forState:UIControlStateNormal];
                } completion:^(BOOL finished){
                    if (self.repeatAnimations)
                    {
                        [self performSelector:@selector(animateArrows) withObject:nil afterDelay:0.0];
                    }
                }];

The reason you need to perform this check is that you have an otherwise infinite loop that is retaining self. Once you leave this loop your view controller will be dealloc'd.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top