2009-10-20 12 views
31

Pobieranie niektórych danych z Facebook Connect (przy użyciu frameworka FBConnect Objective-C 2.0) i robię to wszystko w NSSperation. Jest w NSSperation, ponieważ mam kilka innych operacji, które również działają i to jest jedna z nich.Metody asynchroniczne w NSOperation

Problem polega na tym, że wszystkie wywołania FBConnect są asynchroniczne. Z tego powodu główna metoda NSOperation szybko się kończy, a operacja zostaje oznaczona jako zakończona.

Czy jest jakiś sposób na pokonanie tego? Wygląda na to, że nie ma opcji synchronicznych w FBConnect!

Dziękujemy,

Mike

+0

Jeśli 'FBConnect' natury jest asynchroniczna, jest tam naprawdę jakaś potrzeba użyć' NSOperation' w ogóle? –

+1

No tak, ponieważ jest to jedno z wielu zadań oczekujących w kolejce, a po pobraniu danych jest dużo przetwarzania. –

+2

Dlaczego po utworzeniu asynchronicznego pobierania nie należy utworzyć 'NSOperation' dla tego przetwarzania? –

Odpowiedz

6

umieścić swoje połączenia FBConnect w 'start', a nie 'main' i zarządzać właściwości 'isFinished' 'isExecuting. (i zwróć YES dla "isConcurrent")

Aby uzyskać więcej informacji, zobacz dokumentację Apple na temat pisania concurrent NSOperations.

+3

Od wersji iOS 7.0 powinno się używać 'isAsynchronous' zamiast' isConcurrent'. –

22

Poniżej znajduje się pełny przykład. W swojej podklasie po zakończeniu metody asynchronicznej zadzwoń pod numer [self completeOperation], aby przejść do stanu gotowego.

@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

świetna odpowiedź !!! – eric

+0

To powiedziane ... dla innych zastosowań, jak może klasa, która podklasy NSObject i obsługuje dla ciebie NSOperationQueue ... upewnij się, że impl: - (void) observeValueForKeyPath: (NSString *) keyPath ofObject: (id) object \t \t \t \t \t \t zmiany: (NSDictionary *) kontekst zmiany: (void *) kontekst – eric

+1

Argh. Nie, po prostu nie. Nie definiuj właściwości rozpoczynających się od _. Przedefiniuj istniejące właściwości. W razie potrzeby zadzwoń do 'super'. –

Powiązane problemy