OperationQueue.main vs DispatchQueue.main

Cuando necesite realizar algo en el main thread en el completion block de completion block de una tarea de networking o una operación, ¿cuál de las forms de getla sería la más adecuada y por qué?

  • OperationQueue.main.addOperation
  • DispatchQueue.main.async

    Para get más información sobre las diferencias entre los dos types de queue, consulte la respuesta de León.

    Ambos enfoques funcionarán. Sin embargo, NSOperation se necesita principalmente cuando se requiere una progtwigción más avanzada (incluidas las dependencies , la cancelación , etc.). Entonces, en este caso, un simple

     DispatchQueue.main.async { /* do work */ } 

    Estará bien. Eso sería equivalente a

     dispatch_async(dispatch_get_main_queue(), ^{ /* do work */ }); 

    en Objective-C, que es también cómo lo haría en ese idioma.

    Cuándo usar NSOperation

    La NSOperation API es ideal para encapsular bloques de funcionalidad bien definidos. Podría, por ejemplo, utilizar una subclass NSOperation para encapsular la secuencia de inicio de session de una aplicación.

    El event handling la dependencia es la guinda del pastel. Una operación puede tener dependencies para otras operaciones y esa es una característica poderosa que carece de Grand Central Dispatch. Si necesita realizar varias tareas en un order específico, las operaciones son una buena solución.

    Puede ir por la borda con las operaciones si está creando docenas de operaciones en un corto espacio de time. Esto puede generar problemas de performance debido a la sobrecarga inherente a la NSOperation API .

    Cuándo usar Grand Central Dispatch

    Grand Central Dispatch es ideal si solo necesita enviar un bloque de código a una queue en serie o simultánea.

    Si no quiere pasar por la molestia de crear una NSOperation subclass para una tarea trivial, Grand Central Dispatch es una excelente alternativa. Otra ventaja de Grand Central Dispatch es que puede mantener unido el código relacionado. Eche un vistazo al siguiente ejemplo.

     let dataTask = session.dataTaskWithRequest(request, completionHandler: { (data, response, error) -> Void in // Process Response ... dispatch_async(dispatch_get_main_queue(), { () -> Void in // Update User Interface ... }) }) 

    En el manejador de finalización de la tarea de datos, procesamos la respuesta y actualizamos la interfaz de usuario enviando un cierre (o bloque) a la queue principal. Esto es necesario porque no sabemos en qué subprocess se ejecuta el manejador de finalización y es muy probable que sea un subprocess de background.

    DispatchQueue gestiona la ejecución de elementos de trabajo. Cada elemento de trabajo enviado a una queue se procesa en un grupo de subprocesss administrados por el sistema.

    Referencia: Apple Doc

    La class NSOperationQueue regula la ejecución de un set de objects de Operación. Después de agregarse a una queue, una operación permanece en esa queue hasta que se cancela explícitamente o termina la ejecución de su tarea. Las operaciones dentro de la queue (pero aún no se ejecutan) están organizadas de acuerdo con los niveles de prioridad y las dependencies entre objects de operación y se ejecutan en consecuencia. Una aplicación puede crear varias queues de operaciones y enviar operaciones a cualquiera de ellas.

    Referencia: Apple Doc

    Por lo tanto, debería preferir DispatchQueue.main.async cuando desee realizar algo en el hilo principal desde el bloque de finalización de cualquier llamada de networking. ¡Especialmente cuando está relacionado con las UI Updates ! Y si su tarea es compleja, quiero decir si necesita más operaciones en la tarea de ejecución, entonces puede ir con OperationQueue.main.addOperation contrario, DispatchQueue.main.async dará un performance más óptimo comparativamente.