如何编写Swift 3中的延迟

owl*_*ipe 299 xcode ios swift swift3 dispatch-after

在早期版本的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
}
Run Code Online (Sandbox Code Playgroud)

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

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

owl*_*ipe 889

经过大量的研究,我终于想到了这个.

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

这在Swift 3和Swift 4中创建了所需的"等待"效果.

灵感来自这个答案的一部分.

  • 通过将"+ 2"替换为"+ .seconds(2)",可以使代码更加流畅.或者,为了最终的快捷,你可以放弃第一行并将"截止日期:时间"替换为"截止日期:.now()+.秒(2)". (72认同)
  • 有用的贡献,谢谢!更新最新的Swift 3:`DispatchQueue.main.asyncAfter(截止日期:何时) (7认同)
  • 仍在工作3/12/2017.非常感谢你:) (5认同)
  • 从字面上看,这是我在 SO 上访问量最大的帖子。找到这篇文章比实际记住它或在我的代码中的其他地方找到它更容易;) (4认同)
  • “经过大量研究,我终于找到了这个”......问题和答案的日期时间相同,哈哈 (3认同)
  • @OctavioAntonioCedeño乐于助人.这真让我误解了一段时间:D (2认同)
  • 如果延迟很长,比如 10 分钟,手机就会进入睡眠状态。即使手机在 10 分钟后唤醒,该任务也永远不会运行。 (2认同)

Vic*_* Do 131

我喜欢GCD的单行表示法,它更优雅:

    DispatchQueue.main.asyncAfter(deadline: .now() + 42.0) {
        // do stuff 42 seconds later
    }
Run Code Online (Sandbox Code Playgroud)

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

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

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

顺便说一句,请记住:默认情况下,计时器被添加到默认的运行循环模式.这意味着当此循环模式处于保持状态时(例如,滚动UIScrollView时)可能会冻结计时器.您可以通过将计时器添加到特定的运行循环模式来解决此问题:

RunLoop.current.add(timer, forMode: .commonModes)
Run Code Online (Sandbox Code Playgroud)

在这篇博文中,您可以找到更多详细信息.

  • 加上一个用于Timer比较和关于主runloop的免责声明! (7认同)
  • 接得好!我还没有看到这个. (3认同)
  • 好赶上!这是工程。 (2认同)

Vak*_*kas 52

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

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

用法

delayWithSeconds(1) {
   //Do something
}
Run Code Online (Sandbox Code Playgroud)

  • 你基本上只是复制[这个答案](http://stackoverflow.com/a/24318861/5700898),但是这很好,谢谢. (4认同)
  • 如何取消呢? (2认同)

Ana*_*rma 25

请尝试以下代码进行延迟

//MARK: First Way

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

delayForWork()
Run Code Online (Sandbox Code Playgroud)
// MARK: Second Way

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

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

Pau*_*l B 7

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

sleep(3) // in seconds
usleep   // in 1/million of second 
Run Code Online (Sandbox Code Playgroud)

对于异步编程(Swift 5.5),func 中的暂停如下所示:

func someAsyncFunc() async {
    await Task.sleep(2_000_000_000)  // Two seconds
    // Code to be executed with a delay here
}
Run Code Online (Sandbox Code Playgroud)