【问题标题】:dispatch_after equivalent in NSOperationQueueNSOperationQueue 中的 dispatch_after 等效项
【发布时间】:2013-03-07 00:19:20
【问题描述】:

我正在将我的代码从常规 GCD 移动到 NSOperationQueue,因为我需要一些功能。我的很多代码都依赖于 dispatch_after 才能正常工作。有没有办法用NSOperation 做类似的事情?

这是我的一些代码,需要转换为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)];
    }

});

【问题讨论】:

    标签: ios objective-c xcode grand-central-dispatch nsoperationqueue


    【解决方案1】:

    NSOperationQueue 没有任何计时机制。如果您需要设置这样的延迟然后执行操作,您需要从dispatch_after 调度NSOperation,以便处理延迟并使最终代码成为NSOperation

    NSOperation 旨在处理或多或少的批处理操作。用例与 GCD 略有不同,实际上是在带有 GCD 的平台上使用 GCD。

    如果您要解决的问题是获得可取消的计时器通知,我建议使用NSTimer 并在需要取消时将其无效。然后,为了响应计时器,您可以执行您的代码,或者使用调度队列或 NSOperationQueue。

    【讨论】:

    • 使用计时器与计时器通知会消耗更多资源和电池,并且需要一些额外的工作才能在后台继续。但是取消 yes 更容易。
    【解决方案2】:

    您可以继续将dispatch_after() 与全局队列一起使用,然后在您的操作队列上安排操作。传递给dispatch_after() 的块不会在指定时间之后执行,它们只是在该时间之后调度。

    类似:

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

    【讨论】:

      【解决方案3】:

      您可以创建一个执行睡眠的 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];
      

      【讨论】:

      • 这将使队列中的操作保持活动状态,并且如果队列的活动操作数量有限,睡眠将阻止其他符合条件的操作执行。
      • 同意@Bogdan。这不是一个好方法。你不应该阻塞操作队列线程。
      • 喜欢这个!与其他答案中提出的方法相比,这是最干净的。
      【解决方案4】:
      [operationQueue performSelector:@selector(addOperation:) 
                           withObject:operation 
                           afterDelay:delay];
      

      【讨论】:

        【解决方案5】:

        斯威夫特 4:

        DispatchQueue.global().asyncAfter(deadline: .now() + 10 { [weak self] in
                        guard let `self` = self else {return}
        
                        self. myOperationQueue.addOperation {
                            //...code...
                        }
                    }
        

        【讨论】:

          【解决方案6】:

          晚了七年,但 iOS 7 将此功能引入了 OperationQueue。

          https://developer.apple.com/documentation/foundation/operationqueue/3329365-schedule

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2014-07-24
            • 2013-03-12
            • 1970-01-01
            • 2013-12-16
            • 2018-06-25
            • 2015-07-09
            • 2017-10-24
            • 2014-07-04
            相关资源
            最近更新 更多