【问题标题】:Create several DispatchQueue.main.asyncAfter methods at once in Swift 3在 Swift 3 中一次创建多个 DispatchQueue.main.asyncAfter 方法
【发布时间】:2016-11-25 17:09:56
【问题描述】:

我正在尝试在地图上一个接一个地绘制位置,每个绘制位置之间有 1 秒的间隔,但它并不完全有效。到目前为止,这是我所拥有的:

@IBAction func playButtonPressed(_ sender: Any) {
    var index = 0.0
    var i = 0
    var j = 0
    while i < sites.count {
        while j < sites[i].count {
            DispatchQueue.main.asyncAfter(deadline: .now() + 1.0*index) {
                self.plot(day:i,site:j)
            }
            j += 1
            index += 1
        }
        j = 0
        i += 1
    }
}

func plot(day:Int,site:Int) {
    for letter in glossary {
        let siteToPlot = sites[day][site]
        if let location = letter[siteToPlot] {
            setUpMap(name: location.name!, lat: location.lat!, long: location.long!)
        }
    }
}

按照我的设置方式,for 循环中的每个项目都会有一个在 DispatchQueue.main.asyncAfter 中调用的方法,但每个项目都会在一秒钟后调度。首先是 0 秒后,然后是 1,然后是 2,等等。

似乎没有保存绘图函数参数,但是第一次调用绘图函数时,日期和站点值是 9 和 0,它们是循环完成时的值。

【问题讨论】:

标签: swift asynchronous dispatch


【解决方案1】:

您可以通过创建局部变量来解决此问题:

@IBAction func playButtonPressed(_ sender: Any) {
    var index = 0.0
    var i = 0
    var j = 0
    while i < sites.count {
        while j < sites[i].count {
            let day = i
            let site = j
            DispatchQueue.main.asyncAfter(deadline: .now() + 1.0 * index) {
                self.plot(day: day, site: site)
            }
            j += 1
            index += 1
        }
        j = 0
        i += 1
    }
}

或者,正如 Martin R 在Pass value to closure? 中指出的那样,您可以“捕获”这些变量:

@IBAction func playButtonPressed(_ sender: Any) {
    var index = 0.0
    var i = 0
    var j = 0
    while i < sites.count {
        while j < sites[i].count {
            DispatchQueue.main.asyncAfter(deadline: .now() + 1.0 * index) { [i, j] in
                self.plot(day: i, site: j)
            }
            j += 1
            index += 1
        }
        j = 0
        i += 1
    }
}

或者,就我个人而言,我可能会使用for 循环来稍微清理一下:

@IBAction func playButtonPressed(_ sender: Any) {
    var delay = 0.0
    for i in 0 ..< sites.count {
        for j in 0 ..< sites[i].count {
            DispatchQueue.main.asyncAfter(deadline: .now() + delay) { [i, j] in
                self.plot(day: i, site: j)
            }
            delay += 1
        }
    }
}

【讨论】:

  • 感谢您的帮助罗!
猜你喜欢
  • 2017-04-01
  • 2020-04-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-01-15
  • 2018-05-22
  • 1970-01-01
相关资源
最近更新 更多