在早期的Swift版本中,可以使用以下代码创建延迟:错误出现:“无法将DispatchTime.now转换为期望值dispatch_time_t aka UInt64。”

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

#1 楼

经过大量研究,我终于弄清楚了这一点。 br />受到部分答案的启发。

评论


有用的贡献,谢谢!更新最新的Swift 3:DispatchQueue.main.asyncAfter(截止日期:时间)

–罗加
16年7月7日在16:58

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

–RenniePet
17年1月3日在7:12

@OctavioAntonioCedeño很高兴为您提供帮助。这真的让我烦了一阵子:D

–owlswipe
17 Mar 10 '17 at 0:10

仍在工作2017年3月12日。非常感谢你:)

–约翰·莱昂纳多(John Leonardo)
17年3月13日在2:54

从字面上看,我最常访问的SO帖子。找到这篇文章比实际记住它或在我的代码中的其他地方找到它更容易;)

–barrylachapelle
19年11月7日在19:40

#2 楼

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


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

评论


接得好!我还没看到

– julien_c
16年11月1日在19:45

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

–马丁
17年7月7日在17:04

好赶上!这是工程。

–努尔·阿辛杜(OnurŞahindur)
17-10-15在19:25

#3 楼

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

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


用法

delayWithSeconds(1) {
   //Do something
}


评论


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

–owlswipe
16-10-24在21:01



如何取消呢?

– Sourav Chandra
17年4月5日在9:32

#4 楼

请尝试以下代码进行延迟

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


评论


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

–杰里·庄(Jerry Chong)
19年8月6日在2:56

该程序员在他的代码库中使用的是辅助方法,并且使用了很长时间。因此,延迟是他已经使用了一段时间的代码,但并不知道它与Apple的SDK无关。

–尼克·帕金斯(Nick Perkins)
19-10-17在20:21

#5 楼

一种方法是使用DispatchQueue.main.asyncAfter,因为很多人都回答过。

另一种方法是使用perform(_:with:afterDelay:)。此处更多详情

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

@IBAction func delayedFunc() {
    // implement code
}


#6 楼

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