En línea con mi respuesta a una pregunta relacionada , voy a estar en desacuerdo con BJ y sugerirle que primero mire GCD sobre NSOperation / NSOperationQueue, a menos que este último proporcione algo que necesita que GCD no.
Antes de GCD, utilicé muchas NSOperations / NSOperationQueues dentro de mis aplicaciones para gestionar la concurrencia. Sin embargo, desde que comencé a usar GCD de forma regular, he reemplazado casi por completo NSOperations y NSOperationQueues con bloques y colas de despacho. Esto ha venido de cómo he usado ambas tecnologías en la práctica, y del perfil que he realizado en ellas.
Primero, hay una cantidad de sobrecarga no trivial cuando se usan NSOperations y NSOperationQueues. Estos son objetos Cocoa, y deben asignarse y desasignarse. En una aplicación para iOS que escribí que renderiza una escena tridimensional a 60 FPS, estaba usando NSOperations para encapsular cada cuadro renderizado. Cuando hice un perfil de esto, la creación y el desmantelamiento de estas operaciones de NSO representaban una parte significativa de los ciclos de la CPU en la aplicación en ejecución y ralentizaban las cosas. Los reemplacé con bloques simples y una cola serial GCD, y esa sobrecarga desapareció, lo que condujo a un rendimiento de representación notablemente mejor. Este no fue el único lugar donde noté gastos generales al usar NSOperations, y lo he visto tanto en Mac como en iOS.
En segundo lugar, hay una elegancia en el código de envío basado en bloques que es difícil de igualar cuando se usan NSOperations. Es increíblemente conveniente envolver unas pocas líneas de código en un bloque y enviarlo para que se realice en una cola serial o concurrente, donde la creación de una NSOperation o NSInvocationOperation personalizada para hacer esto requiere mucho más código de soporte. Sé que puedes usar una NSBlockOperation, pero también podrías enviar algo a GCD. Envolver este código en bloques en línea con el procesamiento relacionado en su aplicación conduce, en mi opinión, a una mejor organización del código que tener métodos separados o operaciones NSO personalizadas que encapsulan estas tareas.
NSOperations y NSOperationQueues todavía tienen muy buenos usos. GCD no tiene un concepto real de dependencias, donde NSOperationQueues puede configurar gráficos de dependencia bastante complejos. Utilizo NSOperationQueues para esto en un puñado de casos.
En general, aunque generalmente defiendo el uso del más alto nivel de abstracción que realiza la tarea, este es un caso en el que defiendo la API de nivel inferior de GCD. Entre los desarrolladores de iOS y Mac con los que he hablado sobre esto, la gran mayoría opta por usar GCD sobre NSOperations a menos que estén dirigidos a versiones de SO sin soporte para ellas (anteriores a iOS 4.0 y Snow Leopard).