如何在Swift 3和4中编写dispatch_after GCD?

bra*_*ipt 436 grand-central-dispatch ios swift swift4 swift5

在Swift 2中,我能够dispatch_after使用大中央调度来延迟一个动作:

var dispatchTime: dispatch_time_t = dispatch_time(DISPATCH_TIME_NOW, Int64(0.1 * Double(NSEC_PER_SEC))) 
dispatch_after(dispatchTime, dispatch_get_main_queue(), { 
    // your function here 
})
Run Code Online (Sandbox Code Playgroud)

但这似乎不再在Swift 3(或4)中编译.在Swift 3中使用新的Dispatch API编写它的首选方法是什么?

Rob*_*Rob 1100

语法很简单:

// to run something in 0.1 seconds

DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
    // your code here
}
Run Code Online (Sandbox Code Playgroud)

请注意,增加的上述语法seconds作为Double似乎是混乱(ESP因为我们已经习惯了将纳秒)的来源."添加秒作为Double"语法是有效的,因为它deadline是一个,DispatchTime并且在幕后,有一个+运算符将采取Double并添加许多秒到DispatchTime:

public func +(time: DispatchTime, seconds: Double) -> DispatchTime
Run Code Online (Sandbox Code Playgroud)

但是,如果你真的想要添加整数msec,μs或nsec DispatchTime,你也可以添加DispatchTimeInterval一个DispatchTime.这意味着你可以这样做:

DispatchQueue.main.asyncAfter(deadline: .now() + .milliseconds(500)) {
    os_log("500 msec seconds later")
}

DispatchQueue.main.asyncAfter(deadline: .now() + .microseconds(1_000_000)) {
    os_log("1m ?s seconds later")
}

DispatchQueue.main.asyncAfter(deadline: .now() + .nanoseconds(1_500_000_000)) {
    os_log("1.5b nsec seconds later")
}
Run Code Online (Sandbox Code Playgroud)

这些都可以无缝地工作,因为这个单独的过载方法适用+DispatchTime类中的操作员.

public func +(time: DispatchTime, interval: DispatchTimeInterval) -> DispatchTime
Run Code Online (Sandbox Code Playgroud)

  • 感谢您指出这一点,事实上,https://swift.org/migration-guide/提到需要手动进行更改. (5认同)
  • `DispatchTimeInterval`再现,如`.milliseconds`需要`Int`.但是如果只是添加秒,我会使用`Double`,例如`let n:Double = 1.0; queue.asyncAfter(截止日期:.now()+ n){...}`. (2认同)

Han*_*son 128

斯威夫特4:

DispatchQueue.main.asyncAfter(deadline: .now() + .milliseconds(100)) {
   // Code
}
Run Code Online (Sandbox Code Playgroud)

对于时间.seconds(Int),.microseconds(Int)并且.nanoseconds(Int)也可使用.

  • `.milliseconds`比Double好. (7认同)
  • 非常好.给别人的注释:你也可以使用任何其他的'DispatchTimeInterval`枚举值.`case seconds(Int)``case milliseconds(Int)``case microseconds(Int)``case nanoseconds(Int)` (5认同)
  • `。毫秒优于Double。`-我想要一件T恤;)。 (2认同)

roc*_*ift 58

如果您只想要延迟功能

斯威夫特4

func delay(interval: TimeInterval, closure: @escaping () -> Void) {
     DispatchQueue.main.asyncAfter(deadline: .now() + interval) {
          closure()
     }
}
Run Code Online (Sandbox Code Playgroud)

您可以像以下一样使用它:

delay(interval: 1) { 
    print("Hi!")
}
Run Code Online (Sandbox Code Playgroud)

  • `DispatchQueue.main.asyncAfter(截止日期:.now()+ 0.1,执行:closure)`更简单. (7认同)

Mar*_*rdo 16

在Swift 3发布之后,还必须添加@escaping

func delay(_ delay: Double, closure: @escaping () -> ()) {
  DispatchQueue.main.asyncAfter(deadline: .now() + delay) {
    closure()
  }
}
Run Code Online (Sandbox Code Playgroud)


Suh*_*til 5

斯威夫特4

您可以在DispatchQueue上创建扩展并添加在DispatchQueue内部使用asyncAfter函数的函数延迟

extension DispatchQueue {
   static func delay(_ delay: DispatchTimeInterval, closure: @escaping () -> ()) {
      DispatchQueue.main.asyncAfter(deadline: .now() + delay, execute: closure)
   }
}
Run Code Online (Sandbox Code Playgroud)

并使用

DispatchQueue.delay(.milliseconds(10)) {
   print("task to be done")
}
Run Code Online (Sandbox Code Playgroud)

  • 这与@ rockdaswift的答案有什么不同? (2认同)

Md.*_*san 5

接受答案的风格略有不同。

斯威夫特4

DispatchQueue.main.asyncAfter(deadline: .now() + 0.1 + .milliseconds(500) + 
.microseconds(500) + .nanoseconds(1000)) {
                print("Delayed by 0.1 second + 500 milliseconds + 500 microseconds + 
                      1000 nanoseconds)")
 }
Run Code Online (Sandbox Code Playgroud)