15

Ich verschiebe meinen Code von regulären GCD zu NSOperationQueue, weil ich etwas von der Funktionalität brauche. Ein Großteil meines Codes beruht auf dispatch_after, um ordnungsgemäß zu funktionieren. Gibt es eine Möglichkeit, etwas Ähnliches mit einer NSOperation zu tun?dispatch_after gleichwertig in NSOperationQueue

Dies ist ein Teil meines Codes, der in NSOperation konvertiert werden muss. Wenn Sie ein Beispiel für die Konvertierung mit diesem Code bereitstellen könnten, wäre das großartig.

dispatch_queue_t queue = dispatch_queue_create("com.cue.MainFade", NULL); 
dispatch_time_t mainPopTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(timeRun * NSEC_PER_SEC)); 
dispatch_after(mainPopTime, queue, ^(void){ 
    if(dFade !=nil){ 
     double incriment = ([dFade volume]/[self fadeOut])/10; //incriment per .1 seconds. 
     [self doDelayFadeOut:incriment with:dFade on:dispatch_queue_create("com.cue.MainFade", 0)]; 
    } 

}); 

Antwort

22

NSOperationQueue haben keinen Mechanismus Timing darin. Wenn Sie eine Verzögerung wie diese einrichten und dann eine Operation ausführen müssen, sollten Sie die NSOperation von der dispatch_after einplanen, um sowohl die Verzögerung als auch den endgültigen Code zu behandeln. NSOperation.

NSOperation ist entworfen, um mehr oder weniger Batch-Operationen zu behandeln. Der Anwendungsfall unterscheidet sich geringfügig von GCD und verwendet GCD auf Plattformen mit GCD.

Wenn das Problem, das Sie lösen möchten, eine abbrechbare Timer-Benachrichtigung ist, würde ich vorschlagen, NSTimer zu verwenden und es ungültig zu machen, wenn Sie es abbrechen müssen. Als Reaktion auf den Zeitgeber können Sie dann Ihren Code ausführen oder eine Dispatch-Warteschlange oder NSOperationQueue verwenden.

3

Sie halten dispatch_after() mit einer globalen Warteschlange verwenden, planen Sie dann den Betrieb auf Ihrem Betrieb Warteschlange. Blöcke, die an dispatch_after() übergeben wurden, werden nach der angegebenen Zeit nicht ausgeführt, sie werden einfach nach dieser Zeit geplant.

Etwas wie:

dispatch_after 
(
    mainPopTime, 
    dispatch_get_main_queue(), 
    ^{ 
     [myOperationQueue addOperation:theOperationObject]; 
    } 
); 
1

Sie können eine NSOperation ausführen, die einen Ruhezustand ausführt: MYDelayOperation. Dann fügen Sie es als eine Abhängigkeit für Ihre echte Arbeitsoperation hinzu.

@interface MYDelayOperation : NSOperation 
... 
- (void)main 
{ 
    [NSThread sleepForTimeInterval:delay]; // delay is passed in constructor 
} 

Usage:

NSOperation *theOperationObject = ... 
MYDelayOperation *delayOp = [[MYDelayOperation alloc] initWithDelay:5]; 
[theOperationObject addDependency:delayOp]; 
[myOperationQueue addOperations:@[ delayOp, theOperationObject] waitUntilFinished:NO]; 
+1

Dies wird den Betrieb aktiv in der Warteschlange zu halten, und im Falle einer Warteschlange mit einer begrenzten Anzahl von aktiven Betriebs wird, dass der Schlaf anderen in Frage kommenden Operationen halten aus Ausführen. – Bogdan

+2

Vereinbart mit @ Bogdan. Dies ist kein guter Ansatz. Sie sollten die Operationswarteschlangen-Threads niemals blockieren. – Randy

0
[operationQueue performSelector:@selector(addOperation:) 
        withObject:operation 
        afterDelay:delay];