2009-10-20 16 views
31

Ich hole Daten von Facebook Connect (mit dem FBConnect Objective-C 2.0 Framework) und mache das alles in einer NSOperation. Es ist in einer NSOperation, weil ich mehrere andere Operationen habe, die auch laufen, und das ist einer von ihnen.Asynchrone Methoden in NSOperation

Das Problem ist, dass alle FBConnect-Aufrufe asynchron sind. Aus diesem Grund wird die Hauptmethode der NSOperation schnell beendet und die Operation wird als abgeschlossen markiert.

Gibt es einen Weg, dies zu überwinden? Es scheint, dass es in FBConnect keine synchronen Optionen gibt!

Vielen Dank,

Mike

+0

Wenn 'FBConnect' von Natur aus asynchron ist, muss wirklich eine' NSOperation' verwendet werden? –

+1

Nun ja, es ist eine von vielen eingereihten Aufgaben und es gibt eine Menge von Verarbeitung, die auftritt, nachdem die Daten heruntergeladen wurden. –

+2

Warum nicht die 'NSOperation' für diese Verarbeitung erstellen, nachdem der asynchrone Download abgeschlossen ist? –

Antwort

6

setzen Sie Ihre FBConnect Anrufe in 'start', nicht 'main' und verwalten 'isFinished' 'isExecuting Eigenschaften'. (und senden Sie 10 für 'isConcurrent')

Weitere Informationen finden Sie in Apples Dokumentation zum Schreiben concurrent NSOperations.

+3

Ab iOS 7.0 sollte 'isAsynchronous' anstelle von' isConcurrent' verwendet werden. –

22

Unten ist ein vollständiges Beispiel. Rufen Sie in Ihrer Unterklasse nach Abschluss der asynchronen Methode [self completeOperation] auf, um in den fertigen Zustand überzugehen.

@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

großartige Antwort !!! – eric

+0

Das sagte ... für andere Zwecke, wie vielleicht eine Klasse, die NSObject subclasses, und behandelt die NSOperationQueue für Sie ... stellen Sie sicher impl: - (void) observeValueForKeyPath: (NSString *) keyPath ofObject: (id) Objekt \t \t \t \t \t \t Änderung: (NSDictionary *) Änderung Kontext: (void *) Kontext – eric

+1

Argh. Nein einfach nein. Definieren Sie keine Eigenschaften, die mit _ beginnen. Definieren Sie die vorhandenen Eigenschaften neu. Ruf 'super' an, wenn du musst. –

Verwandte Themen