Hay un video de WWDC (2012) que probablemente lo ayude. Utiliza un NSOperationQueue
personalizado y coloca los bloques asíncronos dentro de NSOperations
para que pueda mantener un control sobre los bloques y cancelar los bloques restantes en cola.
Una idea sería tener el manejo de errores de los bloques secundarios para llamar a un método en el hilo principal en la clase que maneja el NSOperationQueue
. La clase podría cancelar el resto apropiadamente. De esta forma, el bloqueo para niños solo necesita conocer su propio hilo y el hilo principal. Aquí hay un enlace al video
https://developer.apple.com/videos/wwdc/2012/
El video se llama "La construcción de interfaces de usuario concurrentes en iOS". La parte relevante se encuentra principalmente en la segunda mitad, pero es probable que desee ver todo, ya que lo contextualiza.
EDIT:
Si es posible, me gustaría recomendar el manejo de la respuesta en un bloque incorporado, que lo envuelve muy bien juntos, que es lo que pienso que está buscando ..
//Define an NSBlockOperation, and get weak reference to it
NSBlockOperation *blockOp = [[NSBlockOperation alloc]init];
__weak NSBlockOperation *weakBlockOp = blockOp;
//Define the block and add to the NSOperationQueue, when the view controller is popped
//we can call -[NSOperationQueue cancelAllOperations] which will cancel all pending threaded ops
[blockOp addExecutionBlock: ^{
//Once a block is executing, will need to put manual checks to see if cancel flag has been set otherwise
//the operation will not be cancelled. The check is rather pointless in this example, but if the
//block contained multiple lines of long running code it would make sense to do this at safe points
if (![weakBlockOp isCancelled]) {
//substitute code in here, possibly use *synchronous* NSURLConnection to get
//what you need. This code will block the thread until the server response
//completes. Hence not executing the following block and keeping it on the
//queue.
__block NSData *temp;
response = [NSData dataWithContentsOfURL:[NSURL URLWithString:urlString]];
[operationQueue addOperationWithBlock:^{
if (error) {
dispatch_async(dispatch_get_main_queue(), ^{
//Call selector on main thread to handle canceling
//Main thread can then use handle on NSOperationQueue
//to cancel the rest of the blocks
});
else {
//Continue executing relevant code....
}
}];
}
}];
[operationQueue addOperation:blockOp];
Gracias, he visto el video. Supongo que lo que estoy tropezando es cómo una operación esencialmente puede mantenerse en la cola mientras espera una respuesta asincrónica ...? Sería conveniente poder aprovechar NSOperationQueue. He usado esa clase anteriormente en otras aplicaciones, pero anteriormente solo hacía que la cola manejara las solicitudes de salida, no el procesamiento de respuesta. En esta aplicación, la operación no finaliza hasta que se procesa la respuesta y las solicitudes secundarias asociadas también se completan. – xyzzycoder
¿puedes poner el código de manejo de respuesta en un bloque integrado? Actualizaré mi respuesta –
Si está en el mundo 'NSOperation', en lugar de' dispatch_async (dispatch_get_main_queue(),^{}); ', ¿por qué no' [[NSOperationQueue mainQueue] addOperationWithBlock:^{}]; ' ? Lo que tienes está bien, pero se siente extraño mezclar llamadas GCD con llamadas 'NSOperationQueue'. – Rob