2010-04-05 15 views
7

Nuestra aplicación ha fallado con una frecuencia de aproximadamente 1 en 1.500 lanzamientos debido a un error que está resultando difícil de alcanzar. La parte relevante del seguimiento de la pila está incluida. Se está disparando como una devolución de llamada, así que no tengo ninguna referencia de dónde está ocurriendo en mi propio código.UIAlertView falla en el método no documentado

Parece que lo que está pasando es que hay un objeto UIViewAnimationState que llama al método privado UIAlertView's (_popoutAnimationDidStop:finished:). El único problema es que parece que el UIAlertView ha sido desastrado por este punto. No hago nada raro con vistas de alerta. Los vomito y espero la entrada del usuario. Todos se muestran antes de ser lanzados.

¿Alguien ha encontrado esto? En este punto, me inclino a que sea un error de Apple.

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

¿recuerda el error recibido en el depurador? fue posible: [* respondsToSelector:]: mensaje enviado a instancia desasignada – Cole

Respuesta

12

Es probable que UIAlertView está intentando llamar a un método en su delegado después de que el delegado ha sido puesto en libertad. Para evitar este tipo de error, cada vez que configura un objeto como delegado de otro objeto, establezca la propiedad delegar en nulo en el método dealloc del objeto delegado. p.ej.


@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

Gracias perfecto. Solución obvia, me quedé colgado en el supuesto de que era UIAlertView de alguna manera se lanzó de forma prematura. A veces solo necesitas verlo otra vez. Para cualquier otra persona que se encuentre con esto, tenga en cuenta que si está utilizando una pila de navegación que puede ser presionada/reventada de forma no determinista (por ejemplo, en la pérdida de conexión), siempre debe desconectar a los delegados en su dealloc. Apple NO ilustra este patrón correctamente en sus proyectos de ejemplo. – DougW

+3

Me enfrento al mismo problema. ¿Podría alguien señalar cómo resolver esto cuando AlertView se declara como una variable local? ¿Tenemos que configurar el delegado en cero en la devolución de llamada del delegado? – rustylepord

+0

Es interesante que ocurra incluso en aplicaciones compiladas en modo ARC. ¿Por qué Apple no hizo que las propiedades de los delegados de UIAlertView sean débiles, como lo recomiendan para todas las propiedades similares a las de los delegados? – Lukasz

Cuestiones relacionadas