2010-04-05 13 views
7

Unsere App stürzte mit einer Häufigkeit von ungefähr 1 von 1.500 Starts ab, weil ein Bug sich als schwer fassbar herausstellte. Der relevante Teil der Stapelverfolgung ist enthalten. Es wird als Rückruf abgefeuert, so dass ich keinen Hinweis darauf habe, wo es in meinem eigenen Code vorkommt.UIAlertView-Absturz bei undokumentierter Methode

Es sieht so aus, als ob es ein UIViewAnimationState Objekt gibt, das UIAlertView's private Methode (_popoutAnimationDidStop:finished:) aufruft. Nur Problem ist, scheint es, dass die UIAlertView von diesem Punkt gelöst wurde. Ich mache mit Alarmsichten nichts Seltsames. Ich werfe sie hoch und warte auf Benutzereingaben. Sie werden alle vor der Veröffentlichung angezeigt.

Wer ist diesem begegnet? An diesem Punkt lehne ich mich darauf hin, dass es ein Apple Bug ist.

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

+0

erinnern Sie sich an den Fehler im Debugger erhalten? war es möglicherweise: [* antwortetToSelector:]: Nachricht, die an freigegebene Instanz – Cole

Antwort

12

Es ist wahrscheinlich, dass UIAlertView eine Methode auf seinem Delegierten zu nennen, nachdem die Delegierten freigegeben wurde versucht. Um diesen Fehlertyp zu verhindern, müssen Sie jedes Mal, wenn Sie ein Objekt als Delegat eines anderen Objekts festlegen, die delegate-Eigenschaft in der Dealloc-Methode des Delegatobjekts auf null setzen. z.B.


@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 
+1

gesendet wird Perfect thanks. Offensichtliche Lösung, ich habe gerade aufgelegt, dass es der UIAlertView war, der irgendwie vorzeitig veröffentlicht wurde. Manchmal muss man nur noch einen Blick darauf werfen. Falls Sie einen Navigations-Stack verwenden, der nicht-deterministisch (z. B. bei Verbindungsverlust) verschoben werden kann, müssen Sie alle Delegierten in Ihrem Dealloc deaktivieren. Apple veranschaulicht dieses Muster NICHT in ihren Beispielprojekten. – DougW

+3

Ich stehe vor dem gleichen Problem. Könnte jemand darauf hinweisen, wie dies gelöst werden kann, wenn AlertView als lokale Variable deklariert wird. Müssen wir den Delegaten im Delegaten-Callback auf null setzen? – rustylepord

+0

Interessant, dass es sogar in Apps passiert, die im ARC-Modus kompiliert wurden. Warum hat Apple die delegate-Eigenschaft von UIAlertView nicht so sicher gemacht, wie sie für alle delegentenähnlichen Eigenschaften empfiehlt? – Lukasz

Verwandte Themen