2012-06-14 12 views
6

Estoy creando un UIActionSheet en actionSheet: clickedButtonAtIndex método delegado.UIActionSheet tarda mucho tiempo para responder

- (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex  
if(buttonIndex == 1){ 

     [self.myFirstView removeFromSuperview]; 

     if (!self.mySecondView) { 
      [[NSBundle mainBundle] loadNibNamed:@"MySecondView" owner:self options:nil]; 
     } 
     [self.mySecondView setFrame:CGRectMake(0, 0, 320, 480)]; 

     [[UIApplication sharedApplication].keyWindow addSubview: self.mySecondView]; 

     UIActionSheet * action = [[UIActionSheet alloc]initWithTitle:@"" 
                  delegate:self 
                cancelButtonTitle: nil 
               destructiveButtonTitle: deleteContacts 
                otherButtonTitles: cancel, nil]; 
     action.tag = 102; 
     [action showInView:self.view]; 
     [action release]; 

    } 

que controlen el evento clic de este UIActionSheet en el mismo método exacto que el anterior.

if(actionSheet.tag == 102){ 

    if(buttonIndex == 0){ 
     if([[NSBundle mainBundle] loadNibNamed:@"MyThirdView" owner:self options:nil]) { 
      [self.myThirdView setFrame:CGRectMake(0, 0, 320, 480)]; 
      [[UIApplication sharedApplication].keyWindow addSubview:self.myThirdView]; 
     } 
     [self.mySecondView removeFromSuperview]; 

     [self.doneButton.target performSelector:self.doneButton.action withObject:self.doneButton.target]; 

     [self performSelector:@selector(RemoveView) withObject:self afterDelay:3.0]; 

    } 
} 

El problema que estoy enfrentando es que, la UIActionSheet toma demasiado tiempo para responder. Cuando hago clic en el botón UIActionSheet, se congela durante 2 o 3 segundos, antes de que se carguen myThirdView. No puedo entender, ¿cuál es el retraso de respuesta en este caso, ya que lo primero que hago en el UIActionSheet botón haga clic en el método de evento es cargar myThirdView. El resto del código se ejecuta solo después del código para cargar myThirdView. Pero incluso la primera línea de código parece ejecutarse después de un retraso. ¿Alguna sugerencia?

+0

Funciona cuando se cambia '[showInView acción: self.view];' a '[showInView acción: self.mySecondView];'? – Felix

+0

Funciona. Pero no hay cambios significativos en la velocidad de respuesta de la hoja de acción. –

+0

Creo que la respuesta correcta debería ser combinar las respuestas de The Saad y Andrew Zimmer. El código que debería ejecutarse en el hilo de fondo es esta línea de código '[self.doneButton.target performSelector: self.doneButton.action withObject: self.doneButton];'. El resto del código, incluido el método 'RemoveView', debe ejecutarse en el hilo principal. Mención especial a Gabriel por simular una acción táctil. –

Respuesta

2

Pregunta. ¿La hoja de UIActionSheet se congela, o desaparece y la tercera vista no es visible durante 2-3 segundos?

Esto podría deberse a 1 de 2 problemas.

  1. si toda la congelación de la hoja de la acción, entonces usted está haciendo algún trabajo pesado cuando init que tercera vista, que va a cargar algunos datos básicos, o una gran cantidad de activos, o algo que se está llevando mucho tiempo. Si este es el caso, tendrá que reformatear CÓMO cargar esa tercera vista. Te sugiero que cargues cualquier carga pesada en el fondo (esto significa que si tienes muchas imágenes en tu xib, puedes necesitar cargarlas en el código).

  2. La otra posibilidad es que esté agregando la 3ª vista debajo de la 2ª vista y luego no oculte la 2ª vista durante 3 segundos (realice el selector con un retraso). Si este es el caso, simplemente elimine la demora.

hice un par de clases para ayudarme ejecuciones de tiempo y encontrar los cuellos de botella en mi código, parece que podrían ayudar ahora. http://forrst.com/posts/Code_Execution_Timer_for_iOS_Development-dSJ

3

esto es tal vez debido a este

[self performSelector:@selector(RemoveView) withObject:self afterDelay:3.0]; 

HACER UNA otros métodos y hacer esto en ese método. como esto

[self viewRemover]; 

y en viewRemover

-(void) viewRemover 
{ 
    [self performSelector:@selector(RemoveView) withObject:self afterDelay:3.0]; 

} 

lo que el código será así acciones de la interfaz ahora

if(actionSheet.tag == 102){ 

    if(buttonIndex == 0){ 
     if([[NSBundle mainBundle] loadNibNamed:@"MyThirdView" owner:self options:nil]) { 
      [self.myThirdView setFrame:CGRectMake(0, 0, 320, 480)]; 
      [[UIApplication sharedApplication].keyWindow addSubview:self.myThirdView]; 
     } 
     [self.mySecondView removeFromSuperview]; 

     [self.doneButton.target performSelector:self.doneButton.action withObject:self.doneButton.target]; 

    [self performSelectorInBackground:@selector(viewRemover) withObject:nil]; 

    } 
} 
+0

Probé eso. No funciona. –

+0

ver actualizado ans – Saad

+0

he cambiado la línea – Saad

3

usuario ejecute en el hilo principal y sólo se producen cuando finaliza su método. Por lo tanto, MyThirdView no aparecerá hasta que las otras instrucciones hayan finalizado. El único que se me ocurre es retrasar o sea:

[self.doneButton.target performSelector:self.doneButton.action withObject:self.doneButton.target]; 

Si usted está haciendo ningún cálculo pesado o conexión a red, para asegurarse de que es la razón.

otoh, creo que será mejor que modificar esa línea:

[self.doneButton.target performSelector:self.doneButton.action withObject:self.doneButton]; 

si desea simular una acción de botón táctil.

+0

No se realizaron diferencias significativas. –

1

¿Qué tan grande es su tercera vista. Si el archivo Nib necesita cargar demasiado, es posible que esté esperando que suceda mucho, también si tiene que cambiar algunos elementos de la interfaz de usuario y bloquear el hilo de la interfaz de usuario, usted llamará a su aplicación hasta que se agote el tiempo de espera y la aplicación cambie algunas cosas para compensar ..

la ruta tomo con esto es dispatch_async y dispatch_sync

// This will release the UI thread which may be blocking your calls. 
// You can use any of the DISPATCH_QUEUE_PRIORITY_.... values to set how important this block is. 
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{ 
    // this command will get added to the stack and return without a hitch. 
    // the block will be run the next time the main runloop ends. 
    dispatch_async(dispatch_get_main_queue(), ^{ 
     // do some UI work that can happen without a hitch, and does not impact the calling block 
    }); 

    // this command will act much the same. but will pause the background execution 
    // of this block until the runloop has executed this and returned. 
    dispatch_sync(dispatch_get_main_queue(), ^{ 
     // do some UI work that must be completed to continue. 
    }); 

}); 

hacer demasiado en el hilo de interfaz de usuario hará una pausa en la ejecución de las cosas que se apilan en la cola. Enviar todo el código al hilo de fondo y solo saltar al hilo de la interfaz de usuario cuando necesite modificar la interfaz de usuario es una forma mejor y más sensible de codificar su aplicación de iPhone.

espero que esto ayude :)

+0

Este bloque de código ha sido un salvavidas para mí. ASEGÚRESE DE NO PASAR OBJETOS DE AUTORELEASE PARA ELLO. Como es un bloque, a veces sientes que puedes. –

+0

Actualmente estoy usando arco. Pero creo que el bloque conserva y libera los objetos que tiene por sí solo. ¿No? –

+0

No estoy seguro si funciona cuando está usando ARC, por lo que podría estar bien. Pasar objetos lanzados automáticamente entre hilos es bastante desastroso si no estás en ARC. Me he quemado por esto en el pasado. –

Cuestiones relacionadas