【问题标题】:Why putting a DispatchQueue delay function inside another DispatchQueue has no effect in Swift为什么将 DispatchQueue 延迟函数放在另一个 DispatchQueue 中在 Swift 中没有效果
【发布时间】:2017-04-09 14:42:11
【问题描述】:

预期行为:

对于 i = 0,打印语句在 0 秒后调用。

对于 i = 1,打印语句在 1.1 秒后调用

对于 i = 2,打印语句在 2.2 秒后调用

实际行为:

分别在0、1、2、3秒后调用打印语句,即忽略内部延迟功能。

那么为什么会出现这种差异?

    for i in 0...3 {

        DispatchQueue.main.asyncAfter(deadline: .now() + .seconds(i), execute: {  

            DispatchQueue.main.asyncAfter(deadline: .now() + .seconds(i/10), execute: {
                print("function was called")
            })      
        })
    }

【问题讨论】:

  • 但是问题是什么?你希望做什么
  • 使其每隔1秒执行一次打印语句
  • 好吧,你的代码不会那样做; for in 0...5立即执行所有循环。
  • 但这已经被回答了数百次了。就个人而言,我会使用 delay 并使用递归而不是循环。但是此外,您要求做的完全是人为的;在现实生活中没有人会这样做。你最好问问你想要解决的真正的问题。

标签: loops swift3 xcode8 delay delayed-execution


【解决方案1】:

有很多方法可以做到这一点。这里有 3 个:

使用计时器每秒重复一个块

var i = 0
Timer.scheduledTimer(withTimeInterval: 1, repeats: true) { timer in
    i += 1
    print("hello \(i)")
    if i == 5 {
        timer.invalidate()
    }
}

调度多个异步任务

for i in 1...5 {
    DispatchQueue.main.asyncAfter(deadline: .now() + .seconds(i)) {
        print("hello \(i)")
    }
}

注意:这会将所有任务预先排入队列,如果有大量任务,可能会导致队列溢出。

在后台运行循环并休眠并切换到前台打印

DispatchQueue.global().async {
    for i in 1...5 {
        sleep(1)
        DispatchQueue.main.async {
            print("hello \(i)")
        }
    }
}

注意:如果循环中的工作需要大量时间,这会稍微漂移(不会相隔 1 秒)。

【讨论】:

  • DispatchQueue.global() 有默认睡眠吗?我认为它自己有 1 秒的睡眠时间。我说的对吗?
  • @MHSFisher,我知道没有内置的 1 秒睡眠。我写的方式,睡眠是在第一次打印之前,所以在第一次打印出现之前会有1秒的延迟。您可以将睡眠移动到DispatchQueue.main.async 之后,以便更快地开始输出。
  • 我正在无限循环中从DispatchQueue 中的套接字服务器读取,但每个循环的速度就像睡了 1 秒。你对此有什么想法吗?
  • @MHSFisher,我没有。
【解决方案2】:

在另一个调用中嵌入对 DispatchQueue.main.asyncAfter() 的调用是完全有效的。原始代码似乎不起作用的简单原因是第二次调用的截止日期为 .now() + .seconds(i/10),其中 i 是 Int,0/10 == 0, 1/ 10 == 0 等(直到 i 达到 10)。

将代码更改为截止日期:.now() + .seconds((Double(i) / 10.0) 将修复它。

【讨论】:

  • 为什么还要批评其他答案?
  • 对不起。没有意识到指出其他答案是错误的(或者只是不回答原始问题)被认为是批评。以后我会尽量不让社论cmets出来。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-09-18
  • 2021-04-28
  • 2021-12-07
  • 1970-01-01
  • 2018-05-09
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多