2012-10-19 14 views
5

Ich verwende derzeit GCD. Allerdings habe ich gehört, dass NSOperation eigentlich ein höheres Programm ist. Es ist jedoch viel komplexer.Welcher ist einfacher zu benutzen? GCD oder NSOperation?

In GCD, tun Sie etwas im Hintergrund einfach diese Hilfsfunktion verwende ich erstellt:

+(void)doForeGround:(void (^)())block 
{ 
    dispatch_async(dispatch_get_main_queue(), ^{ 
     block(); 
    }); 
} 

+(void)doBackground:(void (^)())block 
{ 

    //DISPATCH_QUEUE_PRIORITY_HIGH 
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW,0), ^{ 
    //dispatch_async(dispatch_get_global_queue(-2,0), ^{ 
     block(); 
    }); 
} 

-(void)doBackGround:(void (^)())block onComletion:(void (^)())onCompletion 
{ 
    [BGHPTools doBackground:^{ 
     block(); 
     [BGHPTools doForeGround:^{ 
      onCompletion(); 
     }]; 
    }]; 
} 

Will es mit NSOperation tun einfacher sein?

Fehle ich etwas? Wie würde ich bei NSoperation dasselbe machen?

Antwort

6

Sie können mit NSOperation ähnliche Dinge tun, wie Sie mit GCD tun. Der Hauptunterschied ist, dass NSOperation zusätzliche Funktionalität bietet.

Zum Beispiel:

  • NSOperation hat eine -cancel Methode. Versandwarteschlangen haben kein Konzept der Stornierung; Alle in einer Warteschlange eingereihten Blöcke werden vollständig ausgeführt.
  • NSOperationQueue verfügt über eine maximumConcurrentOperationCount -Eigenschaft, die Sie (zum Beispiel) verwenden können, um nur 3 Operationen gleichzeitig auszuführen. Versandwarteschlangen haben kein solches Konzept; Sie sind entweder seriell, erlauben nur 1 Block gleichzeitig oder gleichzeitig, so dass sich libdispatch aufgrund der CPU-Auslastung und Verfügbarkeit als ratsam erweist.
  • Eine NSOperation kann eine Abhängigkeit von anderen NSOperation s haben, so dass Sie die Ausführung einer bestimmten Operation aufschieben können, bis alle Abhängigkeiten ausgeführt wurden. Andere Operationen können in der Warteschlange "weiterspringen", während die abhängige Operation wartet. Versandwarteschlangen werden immer in streng FIFO-Reihenfolge aus der Warteschlange genommen. (Sie können etwas Abhängigkeiten imitieren mit dem dispatch_group API, aber das ist wirklich an einer anderen Art von Problem gezielt.)

Nun, wenn Sie nicht eine dieser Funktionen verwendet wird, arbeitet GCD gut. Es gibt nichts falsch mit GCD, per se. Es ist nur, dass NSOperation einen praktischen Wrapper für einige zusätzliche nette Funktionen bietet.

Hier ist, wie Sie Ihre Beispiele umschreiben würde NSOperationQueue oben mit:

+(void)doForeground:(void (^)())block 
{ 
    [[NSOperationQueue mainQueue] addOperationWithBlock:^{ 
     NSLog(@"I'm running on the main thread!"); 
     block(); 
    }]; 
} 

+(void)doBackground:(void (^)())block 
{ 
    // Note; rather than allocating a new NSOperationQueue every time, you could 
    // allocate the queue once and just refer to that queue. For simplicity, I'll 
    // skip that here. 
    [[NSOperationQueue new] addOperationWithBlock:^{ 
     NSLog(@"I'm running asynchronously on whatever thread NSOperationQueue wants!"); 
     block(); 
    }]; 
} 

-(void)doBackground:(void (^)())block onCompletion:(void (^)())onCompletion 
{ 
    [[NSOperationQueue new] addOperationWithBlock:^{ 
     block(); 
     [[NSOperationQueue mainQueue] addOperationWithBlock:^{ 
      onCompletion(); 
     }]; 
    }]; 
} 
+0

Und ich nehme an, dass NSOperation auch ihre eigenen verschachtelten Autorelease-Stacks erstellt? –

+0

https://developer.apple.com/library/mac/#documentation/Cocoa/Reference/NSOperationQueue_class/Reference/Reference.html beschreibt keine Methode namens new. Ah muss es sein, dass die Abkürzung für allok] init] –

+0

'+ new' von' NSObject' geerbt wird, genau wie alloc und init. Und ja, jeder Block der Operation wird in einem Autorelease-Pool leben. –

4

Eine Operation Warteschlange Beispiel für Ihren Vergleich:

- (void)viewDidLoad 
{ 
    // ... 

    self.queue = [[NSOperationQueue alloc] init]; 

    // ... 
} 

- (void)job 
{ 
    // background activities ... 
} 

- (void)startJob 
{ 
    NSInvocationOperation *op = [[NSInvocationOperation alloc] initWithTarget:self 
                    selector:@selector(job) 
                    object:nil]; 
    [self.queue addOperation:op]; 
} 
+1

Ich mag mit Blöcke :) –

+1

Natürlich +1 sowieso. –