tengo una NSOperationQueue que contiene 2 NSOperations y que lleve a cabo uno tras otro por el ajuste setMaxConcurrentOperationCount
a 1.Problemas Queuing concurrente y no concurrentes
Una de las operaciones es una operación estándar no concurrente (solo un método main
) que recupera de forma sincrónica algunos datos de la web (en el hilo de operación separado por supuesto). La otra operación es una operación simultánea ya que necesito usar algún código que se debe ejecutar de forma asíncrona.
El problema es que he descubierto que la operación concurrente solo funciona si se agrega primero a la cola. Si se produce después de cualquier operación no concurrente, entonces extrañamente se llama bien al método start
, pero después de que el método finaliza y configuro mi conexión para volver a llamar a un método, nunca lo hace. No se ejecutan más operaciones en la cola después. Es como si se cuelga después de que regrese el método de inicio, ¡y no se llama a ninguna devolución de llamada desde ninguna conexión de url!
Si mi operación simultánea se pone primero en la cola, todo funciona bien, las devoluciones de llamada asíncronas funcionan y la operación subsiguiente se ejecuta después de que se haya completado. ¡No entiendo para nada!
Puede ver el código de prueba para mi NSOperation concurrente a continuación, y estoy bastante seguro de que es sólido.
¡Cualquier ayuda sería muy apreciada!
principal Observación Tema:
acabo de descubrir que si el funcionamiento en paralelo es el primero en la cola entonces el método [start]
se llama en el hilo principal. Sin embargo, si no está primero en la cola (si está después de concurrente o no concurrente), entonces no se llama al método [start]
en el hilo principal. Esto parece importante ya que se ajusta al patrón de mi problema. ¿Cuál podría ser la razón de ésto?
concurrente Código NSOperation:
@interface ConcurrentOperation : NSOperation {
BOOL executing;
BOOL finished;
}
- (void)beginOperation;
- (void)completeOperation;
@end
@implementation ConcurrentOperation
- (void)beginOperation {
@try {
// Test async request
NSURLRequest *r = [[NSURLRequest alloc] initWithURL:[NSURL URLWithString:@"http://www.google.com"]];
NSURLConnection *c = [[NSURLConnection alloc] initWithRequest:r delegate:self];
[r release];
} @catch(NSException * e) {
// Do not rethrow exceptions.
}
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
NSLog(@"Finished loading... %@", connection);
[self completeOperation];
}
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {
NSLog(@"Finished with error... %@", error);
[self completeOperation];
}
- (void)dealloc {
[super dealloc];
}
- (id)init {
if (self = [super init]) {
// Set Flags
executing = NO;
finished = NO;
}
return self;
}
- (void)start {
// Main thread? This seems to be an important point
NSLog(@"%@ on main thread", ([NSThread isMainThread] ? @"Is" : @"Not"));
// Check for cancellation
if ([self isCancelled]) {
[self completeOperation];
return;
}
// Executing
[self willChangeValueForKey:@"isExecuting"];
executing = YES;
[self didChangeValueForKey:@"isExecuting"];
// Begin
[self beginOperation];
}
// Complete Operation and Mark as Finished
- (void)completeOperation {
BOOL oldExecuting = executing;
BOOL oldFinished = finished;
if (oldExecuting) [self willChangeValueForKey:@"isExecuting"];
if (!oldFinished) [self willChangeValueForKey:@"isFinished"];
executing = NO;
finished = YES;
if (oldExecuting) [self didChangeValueForKey:@"isExecuting"];
if (!oldFinished) [self didChangeValueForKey:@"isFinished"];
}
// Operation State
- (BOOL)isConcurrent { return YES; }
- (BOOL)isExecuting { return executing; }
- (BOOL)isFinished { return finished; }
@end
Código Queuing
// Setup Queue
myQueue = [[NSOperationQueue alloc] init];
[myQueue setMaxConcurrentOperationCount:1];
// Non Concurrent Op
NonConcurrentOperation *op1 = [[NonConcurrentOperation alloc] init];
[myQueue addOperation:op1];
[op1 release];
// Concurrent Op
ConcurrentOperation *op2 = [[ConcurrentOperation alloc] init];
[myQueue addOperation:op2];
[op2 release];
También tengo este mismo problema. Pero en mi caso, el método de inicio también no requiere nuevas operaciones agregadas después de algunas veces. Cola todavía muestra el estado 'En ejecución'. Entonces el método anterior no puede ser usado. ¿Conoces alguna otra solución? Por favor ayuda.. –