7

Our app has been crashing with a frequency of roughly 1 in 1,500 launches due to a bug that is proving elusive. The relevant portion of the stack trace is included. It's being fired as a callback so I have no reference for where it's occurring in my own code.

It looks like what's going on is there is a UIViewAnimationState object that is calling UIAlertView's private method (_popoutAnimationDidStop:finished:). Only problem is, it appears the UIAlertView has been dealloced by this point. I don't do anything weird with alert views. I throw them up, and I wait for user input. They are all shown before being released.

Anyone encountered this? At this point, I'm leaning toward it being an Apple bug.

Thread 0 Crashed:
0   libobjc.A.dylib                 0x3138cec0 objc_msgSend + 24
1   UIKit                           0x326258c4 -[UIAlertView(Private) _popoutAnimationDidStop:finished:]
2   UIKit                           0x324fad70 -[UIViewAnimationState sendDelegateAnimationDidStop:finished:]
3   UIKit                           0x324fac08 -[UIViewAnimationState animationDidStop:finished:]
4   QuartzCore                      0x311db05c run_animation_cal

lbacks

DShah
  • 9,768
  • 11
  • 71
  • 127
DougW
  • 28,776
  • 18
  • 79
  • 107
  • do you remember the error received in the debugger? was it possibly: [* respondsToSelector:]: message sent to deallocated instance – Cole Jan 20 '11 at 18:04

1 Answers1

12

It's likely that UIAlertView is trying to call a method on its delegate after that delegate has been released. To prevent this type of bug, any time you set an object as another object's delegate, set the delegate property to nil in the delegate object's dealloc method. e.g.


@implementation YourViewController
@synthesize yourAlertView;

- (void)dealloc {
    yourAlertView.delegate = nil; // Ensures subsequent delegate method calls won't crash
    self.yourAlertView = nil; // Releases if @property (retain)
    [super dealloc];
}

- (IBAction)someAction {
    self.yourAlertView = [[[UIAlertView alloc] initWithTitle:@"Pushed"
                         message:@"You pushed a button"
                         delegate:self
                         cancelButtonTitle:@"OK"
                         otherButtonTitles:nil] autorelease];
    [self.yourAlertView show];
}

// ...

@end
JOM
  • 8,139
  • 6
  • 78
  • 111
cduhn
  • 17,818
  • 4
  • 49
  • 65
  • 1
    Perfect thanks. Obvious solution, I just got hung up on the assumption that it was the UIAlertView was somehow being released prematurely. Sometimes you just need to get another set of eyes on it. For anyone else coming across this, be aware that if you are using a navigation stack that can be pushed/popped from non-deterministically (eg on connection loss), you need to always unset any delegates in your dealloc. Apple does NOT illustrate this pattern properly in their example projects. – DougW Apr 06 '10 at 21:17
  • 3
    I am facing the same issue, Could somebody point out how to resolve this when AlertView declared as a local variable. Do we have to set the delegate to nil on the delegate callback? – rustylepord Aug 07 '12 at 13:57
  • Interesting that it happens even in apps compiled in ARC mode. Why Apple did not make delegate property of UIAlertView safe weak as they recommend for all delegate-like properties? – Lukasz Sep 26 '13 at 10:58