views:

305

answers:

1

I am receiving crash reports that appear to be from a UIView animation calling a delegate that has been dealloced.

    Thread 0 Crashed:
0   libobjc.A.dylib                 0x334776f6 objc_msgSend + 18
1   UIKit                           0x31c566c4 -[UIViewAnimationState sendDelegateAnimationDidStop:finished:]
2   UIKit                           0x31c565d2 -[UIViewAnimationState animationDidStop:finished:]
3   QuartzCore                      0x30045a26 run_animation_callbacks

I am setting the current view controller as the delegate for animations using the following pattern:

[UIView beginAnimations:nil context:NULL];
[UIView setAnimationBeginsFromCurrentState:YES];
[UIView setAnimationDuration:0.5];
[UIView setAnimationDelegate:self];
...
[UIView commitAnimations];

My question is, how do I set that delegate reference to nil in my dealloc method? Is there some way to retain a reference to an animation? Or fetch animations in progress?

+2  A: 

The CALayer class handles all animations for UIViews. You can access the UIView's layer using the layer property. If you were to replace the first argument of [UIView beginAnimations: context:] with an actual string, it would be possible to access that animation directly using CALayer's animationForKey: and removeAnimationForKey: methods.

In this case though, it might be enough to call [view.layer removeAllAnimations] before dealloc calls [super dealloc]. This will stop any custom UIView animations and, obviously, remove them from its layer.

Endemic
Perfect! Exactly what I was looking for. I don't know how they overlooked the need to unset delegates for animations in the documentation, but we'll be requiring this pattern for safety anywhere animation delegates are set in our projects.
DougW