如何在Swift 3中编写延迟程序


329

在早期版本的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
}

但现在,斯威夫特3时,Xcode自动改变6个不同的东西,但随后出现以下错误:“无法转换DispatchTime.now到预期值dispatch_time_t又名UInt64”。

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

Answers:


965

经过大量研究,我终于找到了答案。

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中创建所需的“等待”效果。

受到这个答案的启发。


7
有用的贡献,谢谢!更新最新的Swift 3:DispatchQueue.main.asyncAfter(deadline: when)
Rogare

77
通过将“ + 2”替换为“ + .seconds(2)”,可以使代码更加快速。或者,为获得最终的快速性,您可以删除第一行并将“ deadline:when”替换为“ deadline:.now()+ .seconds(2)”。
RenniePet

2
@OctavioAntonioCedeño乐于帮助。这真让我
烦恼

5
仍在工作2017年3月12日。非常感谢您:)
John Leonardo

3
从字面上看,我在SO上访问量最大。它比实际记住它还是在我的代码中其他地方查找起来容易得多;)
barrylachapelle

154

我喜欢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)

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


4
接得好!我还没看到
julien_c

8
再加上一个用于计时器比较和关于主运行循环的免责声明!
马丁

2
好赶上!这是工程。
OnurŞahindur17年

56

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

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

用法

delayWithSeconds(1) {
   //Do something
}

5
您基本上只是复制了此答案,但是是的,这很好,谢谢。
owlswipe

2
如何取消呢?
Sourav Chandra

24

尝试以下代码进行延迟

//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
}

1
第一种方式显示有错误“使用未解决的标识符'延迟'”
Jerry Chong

5
该程序员在他的代码库中使用的是辅助方法,并且使用了很长时间。所以延迟是他使用了一段时间的代码,但并不知道它与Apple的SDK无关。
尼克·帕金斯


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
}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.