2012-05-29 17 views
6

me estoy iniciando una tarea de fondo así:¿Está bien llamar a performSelectorOnMainThread: después de llamar a beginBackgroundTaskWithExpirationHandler y la aplicación está en segundo plano?

UIApplication* application = [UIApplication sharedApplication]; 
_backgroundTask = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:^ 
          { 
           [application endBackgroundTask:_backgroundTask]; 
           _backgroundTask = UIBackgroundTaskInvalid; 
          }]; 

La aplicación se envía al fondo y todo está bien.

Algún tiempo después, se cumple cierta condición, y algún objeto termina la ejecución de este código:

[self performSelectorOnMainThread:@selector(doSomething) withObject:nil waitUntilDone:YES]; 

En ese momento, la aplicación se bloquea!

Tenga en cuenta que el objeto se está ejecutando en el hilo principal en este caso particular.

que sustituyen el código anterior con esto:

dispatch_async(dispatch_get_main_queue(), ^{ 
     [self doSomething]; 
    }); 

y todo parece estar bien, el accidente se ha ido.

Lo que me puedo imaginar es que waitUntilDone: SÍ podría ser la diferencia aquí, pero esa es solo mi sensación visceral.

Mi pregunta es:

¿Está permitido el uso de performSelectorOnMainThread: withObject: waitUntilDone: SI cuando la aplicación se ejecuta en segundo plano?

Si ese es el caso, ¿por qué se bloquea la aplicación y por qué dispatch_async resolvió el problema?

¡Gracias de antemano!

+0

¿realmente está haciendo algo en la interfaz de usuario? ¿Está haciendo un trabajo que tiene sentido cuando la aplicación está en segundo plano? Quizás este método no debería ejecutarse en el hilo principal (UI) en popa todo, independientemente de si ve bloqueos o no. – Nate

+0

doSomething no está haciendo nada con la interfaz de usuario. simplemente envía una notificación usando NSNotificationCenter, y nadie está escuchando esa notificación (me aseguré de eliminar a todos los observadores). – Lio

+0

puede publicar el registro de bloqueo? – viggio24

Respuesta

1

Usando performSelectorOnMainThread: withObject: waitUntilDone: YES puede ser la causa de enhebrar interbloqueos. El hilo actual se detiene y espera. Si el hilo principal no termina de realizar el selector a tiempo, el iOS puede matar tu aplicación para inmovilizar el hilo principal durante más tiempo que el permitido (generalmente 10 segundos, a veces menos)

El dispatch_async (dispatch_get_main_queue .. .llamar no bloquea de esa manera. Siempre pone un evento en la cola y espera su turno y el hilo actual continúa sin detenerse

Sin más información acerca de la naturaleza del bloqueo, es difícil decir qué sucedió.

Cuestiones relacionadas