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