我翻遍了苹果的iBook,找不到任何关于它的定义:

有人能解释一下dispatch_after的结构吗?

dispatch_after(<#when: dispatch_time_t#>, <#queue: dispatch_queue_t?#>, <#block: dispatch_block_t?#>)

当前回答

更清晰的结构概念:

dispatch_after(when: dispatch_time_t, queue: dispatch_queue_t, block: dispatch_block_t?)

dispatch_time_t为UInt64。dispatch_queue_t实际上是一个NSObject的类型别名,但是你应该使用你熟悉的GCD方法来获取队列。该区块是一个快速关闭。具体来说,dispatch_block_t定义为()-> Void,相当于()->()。

使用示例:

let delayTime = dispatch_time(DISPATCH_TIME_NOW, Int64(1 * Double(NSEC_PER_SEC)))
dispatch_after(delayTime, dispatch_get_main_queue()) {
    print("test")
}

编辑:

我推荐使用@matt的延时函数。

编辑2:

在Swift 3中,GCD将会有新的包装器。请看这里:https://github.com/apple/swift-evolution/blob/master/proposals/0088-libdispatch-for-swift3.md

原来的例子在Swift 3中是这样写的:

let deadlineTime = DispatchTime.now() + .seconds(1)
DispatchQueue.main.asyncAfter(deadline: deadlineTime) {
    print("test")
}

注意,你可以将deadlineTime声明写为DispatchTime.now() + 1.0,并得到相同的结果,因为+操作符被重写如下(与-类似):

func +(time: DispatchTime, seconds: Double) -> DispatchTime . func +(time: DispatchTime, seconds: Double func +(time: DispatchWalltime, interval: DispatchTimeInterval) -> DispatchWalltime . func +(time: DispatchWalltime, interval: DispatchTimeInterval

这意味着如果您不使用DispatchTimeInterval enum,而只是写一个数字,则假定您使用的是秒。

其他回答

Swift 3和4:

您可以在DispatchQueue上创建一个扩展,并在内部添加使用DispatchQueue asyncAfter函数的函数delay

extension DispatchQueue {
    static func delay(_ delay: DispatchTimeInterval, closure: @escaping () -> ()) {
        let timeInterval = DispatchTime.now() + delay
        DispatchQueue.main.asyncAfter(deadline: timeInterval, execute: closure)
    }
}

使用:

DispatchQueue.delay(.seconds(1)) {
    print("This is after delay")
}

在Swift 5中,在下面使用:

 DispatchQueue.main.asyncAfter(deadline: .now() + 0.2, execute: closure) 

// time gap, specify unit is second
DispatchQueue.main.asyncAfter(deadline: .now() + .seconds(2)) {
            Singleton.shared().printDate()
        }
// default time gap is second, you can reduce it
    DispatchQueue.main.asyncAfter(deadline: .now() + 0.2) {
          // just do it!
    }

另一个帮手来延迟你的代码,这是100%的Swift使用,并可选地允许选择一个不同的线程来运行你的延迟代码:

public func delay(bySeconds seconds: Double, dispatchLevel: DispatchLevel = .main, closure: @escaping () -> Void) {
    let dispatchTime = DispatchTime.now() + seconds
    dispatchLevel.dispatchQueue.asyncAfter(deadline: dispatchTime, execute: closure)
}

public enum DispatchLevel {
    case main, userInteractive, userInitiated, utility, background
    var dispatchQueue: DispatchQueue {
        switch self {
        case .main:                 return DispatchQueue.main
        case .userInteractive:      return DispatchQueue.global(qos: .userInteractive)
        case .userInitiated:        return DispatchQueue.global(qos: .userInitiated)
        case .utility:              return DispatchQueue.global(qos: .utility)
        case .background:           return DispatchQueue.global(qos: .background)
        }
    }
}

现在你只需在主线程上延迟你的代码,就像这样:

delay(bySeconds: 1.5) { 
    // delayed code
}

如果你想延迟你的代码到不同的线程:

delay(bySeconds: 1.5, dispatchLevel: .background) { 
    // delayed code that will run on background thread
}

如果你喜欢一个框架,也有一些更方便的功能,然后签出handysswift。你可以通过Carthage将它添加到你的项目中,然后像上面的例子一样使用它,例如:

import HandySwift    

delay(bySeconds: 1.5) { 
    // delayed code
}

使用这段代码在2.0秒后执行一些UI相关的任务。

            let delay = 2.0
            let delayInNanoSeconds = dispatch_time(DISPATCH_TIME_NOW, Int64(delay * Double(NSEC_PER_SEC)))
            let mainQueue = dispatch_get_main_queue()

            dispatch_after(delayInNanoSeconds, mainQueue, {

                print("Some UI related task after delay")
            })

Swift 3.0版本

以下闭包函数在主线程上执行一些延迟后的任务。

func performAfterDelay(delay : Double, onCompletion: @escaping() -> Void){

    DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + delay, execute: {
       onCompletion()
    })
}

像这样调用这个函数:

performAfterDelay(delay: 4.0) {
  print("test")
}

Swift 3.0 & Swift 4.0 & Swift 5.0中最简单的解决方案

func delayWithSeconds(_ seconds: Double, completion: @escaping () -> ()) {
    DispatchQueue.main.asyncAfter(deadline: .now() + seconds) { 
        completion()
    }
}

使用

delayWithSeconds(1) {
   //Do something
}