2012-03-03 17 views
10

Estoy ejecutando un montón de elementos en segundo plano utilizando dispatch_async y, a veces, quiero matar lo que tengo en la cola, ¿es posible? Por ejemplo, este código se ejecuta en una vista, y luego el usuario retrocede una pantalla. Todas estas acciones disparadas continúan ejecutándose independientemente de la navegación hacia atrás. Lo ideal sería que me gustaría matar a estos artículos de ejecución:matar elementos en una cola dispatch_async en iOS

dispatch_async(dispatch_get_global_queue(2, 0), ^{ 
     for (int i=0; i<[self.manufacturers count]; i++) { 
      NSString *manufacturerID = [[[self.manufacturers objectAtIndex:i] ManufacturerID] stringValue]; 
      [self doSync:manufacturerID withIndex:i setTimer:YES]; 
     } 
    }); 

Si se crea una cola y el nombre y lo suelta sobre la dealloc de la vista de lo que se llama en la que todavía siguen funcionando.

Respuesta

14

No hay una disposición explícita en las colas de envío para la finalización. Para hacer esto, es algo común probar una ubicación de escape para determinar la terminación. Básicamente, sería un semáforo.

NSOperationQueue (una abstracción de nivel más alto, pero aún se crea usando GCD debajo) tiene soporte para cancelar operaciones. Entonces, por ejemplo, puede crear una serie de NSOperations y agregarlas a NSOperationQueue y luego al mensaje -cancelAllOperations en la cola cuando no lo necesite para completar.

Gran parte de la arquitectura que elija dependerá de cuántos de ellos estén funcionando y si tienen diferentes factores desencadenantes. Entre las implementaciones, es probable que NSOperation sea la solución "más limpia", ya que tiene una cola arbitraria que puede ver para que finalicen las operaciones y también puede cancelar las operaciones pendientes. Más abajo en la escala de hack sería una ubicación volátil que cada uno de estos bloques mira dentro de un circuito cerrado para determinar si van a terminar prematuramente. Aún más abajo sería una variable global para la misma función básica.

Al final, incluso la implementación de NSOperation implica una prueba para salir en una ubicación coherente (ya que solo matar un hilo podría provocar inconsistencias en los datos que se operan o en asignaciones/readaptaciones).

2

La mejor manera de hacerlo es crear su propia cola simultánea (no utilizar una de las globales) y luego llamar a dispatch_suspend() en la cola cuando desee detener el procesamiento en ella. En ese momento, lea esto: Dispatch queues: How to tell if they're running and how to stop them

El uso de un indicador de cancelación le permitirá reanudar la cola de modo que todos los bloques restantes simplemente salgan (después de hacer cualquier gestión de memoria que necesiten, como liberar recursos) cuando lo reanude de nuevo. También puede dispatch_release() la cola inmediatamente después de reanudarla.

Cuestiones relacionadas