15

Przenoszę mój kod ze zwykłego GCD do NSOperationQueue, ponieważ potrzebuję niektórych funkcji. Wiele mojego kodu opiera się na dispatch_after, aby działać poprawnie. Czy jest jakiś sposób, aby zrobić coś podobnego z NSOperation?dispatch_after equivalent w NSOperationQueue

To jest część mojego kodu, który należy przekonwertować na NSOperation. Gdybyś mógł podać przykład konwersji za pomocą tego kodu, byłoby wspaniale.

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)]; 
    } 

}); 

Odpowiedz

22

NSOperationQueue nie ma żadnego mechanizmu rozrządu w nim. Jeśli musisz ustawić opóźnienie takie jak to, a następnie wykonać operację, musisz zaplanować NSOperation z dispatch_after, aby obsłużyć zarówno opóźnienie, jak i ostateczny kod: NSOperation.

NSOperation jest przeznaczony do obsługi mniej lub więcej operacji wsadowych. Przypadek użycia nieznacznie różni się od GCD i faktycznie używa GCD na platformach z GCD.

Jeśli problem, który próbujesz rozwiązać, polega na otrzymaniu powiadomienia o anulowaniu, sugeruję użycie NSTimer i unieważnienie go, jeśli chcesz go anulować. Następnie, w odpowiedzi na timer, możesz wykonać swój kod lub użyć kolejki wysyłkowej lub NSOperationQueue.

3

Można nadal używać dispatch_after() z kolejki światowej, a następnie zaplanować działania na kolejki pracy. Bloki przekazane do dispatch_after() nie są wykonywane po określonym czasie, po prostu są planowane po tym czasie.

Coś jak:

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

Można wykonać NSOperation, który wykonuje sleep: MYDelayOperation. Następnie dodaj go jako zależność do rzeczywistej pracy.

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

Zastosowanie:

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

Pozwoli to zachować operację czynny w kolejce, aw przypadku kolejce z ograniczoną liczbą aktywnego działania, że ​​sen będzie posiadał inne dopuszczalne operacje z wykonanie. – Bogdan

+2

Uzgodniono z @Bogdan. To nie jest dobre podejście. Nigdy nie należy blokować wątków kolejki operacji. – Randy

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