15

相當於我正在將我的代碼從常規GCD移動到NSOperationQueue,因爲我需要一些功能。我的很多代碼依賴dispatch_after才能正常工作。有沒有辦法與NSOperation做類似的事情?dispatch_after NSOperationQueue

這是我的一些代碼,需要轉換爲NSOperation。如果您可以提供一個使用此代碼轉換它的示例,那就太好了。

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

}); 

回答

22

NSOperationQueue沒有在任何計時機制。如果您需要設置這樣的延遲,然後執行操作,則您需要安排dispatch_after中的NSOperation以處理延遲並使最終代碼爲NSOperation

NSOperation旨在處理或多或少的批處理操作。用例與GCD稍有不同,實際上在帶有GCD的平臺上使用GCD。

如果您試圖解決的問題是要獲取可取消的計時器通知,我建議使用NSTimer並使其無效,如果您需要取消它。然後,作爲對計時器的響應,您可以執行您的代碼,或使用調度隊列或NSOperationQueue。

3

您可以繼續使用dispatch_after()與全局隊列,然後安排在你的操作隊列中的操作。傳遞給dispatch_after()的塊在指定的時間後不會執行,它們將在該時間之後進行簡單的調度。

喜歡的東西:

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

您可以創建一個執行睡眠的NSOperation:MYDelayOperation。然後將其添加爲您實際工作操作的依賴項。

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

用法:

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

這將保持運行活躍在隊列中,並在積極運作的有限數量的隊列的情況下,睡眠會持有其他合格操作執行。 – Bogdan 2016-10-24 12:55:11

+2

同意@Bogdan。這不是一個好方法。你不應該阻塞操作隊列線程。 – Randy 2017-02-07 04:04:06

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