2009-10-20 16 views
31

estoy ir a buscar algunos datos de Facebook Connect (utilizando el marco FBConnect Objective-C 2.0) y estoy haciendo todo lo que en un NSOperation. Está en NSOperation porque tengo varias otras operaciones que también funcionan y esta es una de ellas.métodos asincrónicos en NSOperation

El problema es que todas las llamadas FBConnect son asíncronas. Debido a esto, el método principal de NSOperation termina rápidamente y la operación se marca como completada.

¿Hay alguna manera de superar esto? ¡Parece que no hay opciones síncronas en FBConnect!

Muchas gracias,

Mike

+0

Si 'FBConnect' es intrínsecamente asíncrono, ¿realmente hay alguna necesidad de utilizar' NSOperation' en absoluto? –

+1

Bueno, sí, ya que es una de las muchas tareas en cola y hay un montón de procesamiento que se produce después de que se descargan los datos. –

+2

¿Por qué no crear 'NSOperation' para ese procesamiento una vez que se completa la descarga asincrónica, entonces? –

Respuesta

6

ponen sus llamadas en FBConnect 'start', no 'main', y administrar las propiedades 'isFinished' '' isExecuting. (Y volver a YES 'isConcurrent')

Para más detalles, consulte la documentación de Apple en la escritura de concurrent NSOperations.

+3

A partir de iOS 7.0, 'isAsynchronous' deben utilizarse en lugar de' isConcurrent'. –

22

A continuación se muestra un ejemplo completo. En su subclase, después de que se complete su método asincrónico, llame al [self completeOperation] para pasar al estado final.

@interface AsynchronousOperation() 
// 'executing' and 'finished' exist in NSOperation, but are readonly 
@property (atomic, assign) BOOL _executing; 
@property (atomic, assign) BOOL _finished; 
@end 

@implementation AsynchronousOperation 

- (void) start; 
{ 
    if ([self isCancelled]) 
    { 
     // Move the operation to the finished state if it is canceled. 
     [self willChangeValueForKey:@"isFinished"]; 
     self._finished = YES; 
     [self didChangeValueForKey:@"isFinished"]; 
     return; 
    } 

    // If the operation is not canceled, begin executing the task. 
    [self willChangeValueForKey:@"isExecuting"]; 
    [NSThread detachNewThreadSelector:@selector(main) toTarget:self withObject:nil]; 
    self._executing = YES; 
    [self didChangeValueForKey:@"isExecuting"]; 

} 

- (void) main; 
{ 
    if ([self isCancelled]) { 
     return; 
    } 

} 

- (BOOL) isAsynchronous; 
{ 
    return YES; 
} 

- (BOOL)isExecuting { 
    return self._executing; 
} 

- (BOOL)isFinished { 
    return self._finished; 
} 

- (void)completeOperation { 
    [self willChangeValueForKey:@"isFinished"]; 
    [self willChangeValueForKey:@"isExecuting"]; 

    self._executing = NO; 
    self._finished = YES; 

    [self didChangeValueForKey:@"isExecuting"]; 
    [self didChangeValueForKey:@"isFinished"]; 
} 

@end 
+0

¡¡excelente respuesta !!! – eric

+0

Dicho esto ... para otros usos, como tal vez una clase que subclasifica NSObject, y maneja el NSOperationQueue para usted ... asegúrese de que impl: - (void) observeValueForKeyPath: (NSString *) keyPath ofObject: (id) objetar \t \t \t \t \t \t cambio: (NSDictionary *) contexto de cambio: (void *) – eric

+1

contexto Argh. No simplemente no. No defina propiedades que comiencen con _. Redefina las propiedades existentes. Llame a 'super' si lo necesita. –

Cuestiones relacionadas