381

在早期版本的 Swift 中,可以使用以下代码创建延迟:

let time = dispatch_time(dispatch_time_t(DISPATCH_TIME_NOW), 4 * Int64(NSEC_PER_SEC))
dispatch_after(time, dispatch_get_main_queue()) {
    //put your code which should be executed with a delay here
}

但是现在,在 Swift 3 中,Xcode 自动更改了 6 种不同的东西,但随后出现以下错误:“Cannot convert DispatchTime.nowto expected value dispatch_time_taka UInt64。”

在 Swift 3 中运行一系列代码之前如何创建延迟?

4

7 回答 7

1104

经过大量研究,我终于弄清楚了这一点。

DispatchQueue.main.asyncAfter(deadline: .now() + 2.0) { // Change `2.0` to the desired number of seconds.
   // Code you want to be delayed
}

这会在 Swift 3 和 Swift 4 中创建所需的“等待”效果。

受到这个答案的一部分的启发。

于 2016-06-25T17:30:44.493 回答
198

我喜欢 GCD 的单行符号,它更优雅:

    DispatchQueue.main.asyncAfter(deadline: .now() + 42.0) {
        // do stuff 42 seconds later
    }

此外,在 iOS 10 中,我们有新的 Timer 方法,例如块初始化器:

(因此延迟的行动可能会被取消)

    let timer = Timer.scheduledTimer(withTimeInterval: 42.0, repeats: false) { (timer) in
        // do stuff 42 seconds later
    }

顺便说一句,请记住:默认情况下,定时器被添加到默认的运行循环模式。这意味着当用户与您的应用程序的 UI 交互时(例如,滚动 UIScrollView 时),计时器可能会被冻结。您可以通过将计时器添加到特定的运行循环模式来解决此问题:

RunLoop.current.add(timer, forMode: .common)

在此博客文章中,您可以找到更多详细信息。

于 2016-10-31T21:09:37.137 回答
59

尝试以下在Swift 3.0 及更高版本中实现的功能

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

用法

delayWithSeconds(1) {
   //Do something
}
于 2016-10-24T06:04:27.317 回答
19

试试下面的代码延迟

//MARK: First Way

func delayForWork() {
    delay(3.0) {
        print("delay for 3.0 second")
    }
}

delayForWork()

// MARK: Second Way

DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
    // your code here delayed by 0.5 seconds
}
于 2018-05-31T12:18:36.993 回答
4

一种方法是使用DispatchQueue.main.asyncAfter很多人的回答。

另一种方法是使用perform(_:with:afterDelay:). 更多细节在这里

perform(#selector(delayedFunc), with: nil, afterDelay: 3)

@IBAction func delayedFunc() {
    // implement code
}
于 2019-07-25T11:09:58.770 回答
1

//x秒后运行函数

public static func runThisAfterDelay(seconds: Double, after: @escaping () -> Void) {
    runThisAfterDelay(seconds: seconds, queue: DispatchQueue.main, after: after)
}

public static func runThisAfterDelay(seconds: Double, queue: DispatchQueue, after: @escaping () -> Void) {
    let time = DispatchTime.now() + Double(Int64(seconds * Double(NSEC_PER_SEC))) / Double(NSEC_PER_SEC)
    queue.asyncAfter(deadline: time, execute: after)
}

//利用:-

runThisAfterDelay(seconds: x){
  //write your code here
}
于 2018-02-28T13:09:50.490 回答
1

最常用的东西是asyncAfter()Timer。但是如果阻塞线程是可以的,那么有一个选项:

sleep(3) // in seconds
usleep   // in 1/million of second 

对于异步编程(Swift 5.5),在 func 中暂停看起来像这样:

func someAsyncFunc() async {
    await Task.sleep(2_000_000_000)  // Two seconds
    // Code to be executed with a delay here
}
于 2021-10-31T17:21:19.590 回答