2009-10-03 12 views
6

Estoy trabajando con un código que funciona de forma asíncrona con varias devoluciones de llamadas; Snow Leopard ha hecho esto increíblemente fácil con bloques y GCD.¿Qué tan ligero es NSOperationQueue en Snow Leopard?

estoy llamando desde un NSTaskNSBlockOperation así:

[self.queue addOperationWithBlock:^{ 
    NSTask *task = [NSTask new]; 
    NSPipe *newPipe = [NSPipe new]; 
    NSFileHandle *readHandle = [newPipe fileHandleForReading]; 
    NSData *inData = nil; 
    [task setLaunchPath:path]; 
    [task setArguments:arguments]; 
    [task launch]; 

    while ((inData = [readHandle availableData]) && [inData length]) { 
     [[NSOperationQueue mainQueue] addOperationWithBlock:^{ 
      // callback 
     }]; 
    } 

    [task waitUntilExit]; 
}]; 

Este enfoque funciona perfectamente. Es como magia, siempre y cuando mis callbacks manejen la concurrencia correctamente.

Ahora, deseo poder unir algunas de estas llamadas; esto está dentro del método de "actualización" de un objeto modelo y puede llevar mucho tiempo completarlo. Hacer que el usuario golpee el botón de actualización no debe atar la máquina y todo eso.

Veo un dilema de implementación aquí. Puedo hacer un montón de colas, una por tipo de llamada, y establecer sus recuentos de operaciones simultáneas en 1 y luego llamar al -cancelAllOperations cada vez que es hora de una nueva llamada.

De manera alternativa, podría hacer un poco más de contabilidad manual sobre qué llamadas están ocurriendo actualmente y gestionar una única cola por objeto modelo (como lo estoy haciendo) o podría ir más allá y usar una cola global.

¿Cuánto pesa NSOperationQueue? ¿Crear muchas colas es una mala decisión de arquitectura? ¿Hay una mejor manera de unir estas tareas?

+2

FYI, estás perdiendo tu NSTask y tu NSPipe. + nuevo es equivalente a + alloc/-init, lo que significa que eres responsable de liberarlos ... lo cual nunca haces (en tu código anterior). (a menos que, por supuesto, esté usando GC) –

+1

Es un programa solo de Snow Leopard. Espero que su nuevo código Snow-Leopard-only sea recogido basura. :-D –

Respuesta

8

Si le preocupa el rendimiento, no lo adivine: mida y luego solucione los cuellos de botella que encuentre. Agregar colas es simple; pruébalo y mira lo que Instruments te dice sobre el efecto en el rendimiento.

La razón principal para crear múltiples colas es en caso de que tenga algún motivo para querer iniciarlas y detenerlas. Si solo desea obtener los beneficios de libdispatch, puede obtenerlo simplemente agregando operaciones a la cola principal.

0

Simplemente use tantas colas de operación como desee. Están aquí para separar partes lógicas de tu programa. No creo que deba preocuparse demasiado por el rendimiento, siempre y cuando no esté asignando cientos de colas por segundo.

+0

Sitio web? ¿Qué tiene esto que ver con los sitios web? –

+0

Gracias, todavía es muy temprano en la mañana. :) –

1

Puede agregar varios bloques a un NSBlockOperation que se ejecutará simultáneamente y puede cancelarse mediante cancelando la operación contenedora. Siempre que sus tareas individuales no tengan que ser serializadas, esto puede funcionar.

+0

Eso no es lo que dicen los documentos: "La clase NSBlockOperation es una subclase concreta de NSOperation que gestiona la ejecución concurrente de uno o más bloques". http://developer.apple.com/mac/library/DOCUMENTATION/Cocoa/Reference/NSBlockOperation_class/Reference/Reference.html –

+0

Jim, tiene toda la razón. Respuesta actualizada Gracias. –

Cuestiones relacionadas