在 Swift 中将 for 循环与计时器同步

Synchronizing a for loop with timers in Swift

我正在处理的部分应用程序涉及存储在对象数组中的一系列计时器。理想情况下,我想遍历这个数组,获取计时器的持续时间并继续倒计时。计时器结束后,转到数组中的下一项并重复该过程

for(index, content) in enumerate timerList{
    doneTimer = NSTimer.scheduledTimerWithTimeInterval(timerList[index].duration, target: self, selector: Selector("finished:"), userInfo: nil, repeats: false)
}

func finished(timer : NSTimer){
     //do whatever and tell the loop to get the next item?
}

放置这个 for 循环 "on hold" 直到计时器结束再转到数组中的下一项的最佳方法是什么?

在任何类型的 GUI 应用程序中,基本规则之一是您永远不想 "pause" 或 "stop" 或 "wait." 相反,您想要做的是开始一个操作稍后将完成,返回 GUI,然后当该操作完成时,从您停止的地方继续。

在您问题的上下文中,您尝试做的似乎是找到最近的计时器,启动它,在 GUI 中显示一些内容,然后在计时器触发之前不执行任何操作。

考虑到这一点,您要采用的基本模型是找到最早的计时器,启动它,在 GUI 中显示一些内容,然后返回系统。当该计时器触发时,您可以重复该过程。

你原来的问题有很多含糊不清的地方,你最终会得到这样的结果:

class TimerController {
    var timers = [Timer]()
    var runningTimer : NSTimer?
    var countDownDisplay : UILabel?

    class Timer {
        let fireDate : NSDate

        init(fireDate:NSDate) {
            self.fireDate = fireDate
        }
    }

    // given an array of NSTimer, find the earliest one to fire
    func findEarliestTimer() -> Timer? {
        return timers.sorted( { return [=10=].fireDate.timeIntervalSince1970 < .fireDate.timeIntervalSince1970 } ).first
    }

    func scheduleEarliestTimer() {
        runningTimer?.invalidate()
        runningTimer = nil

        if let timer = findEarliestTimer() {
            let duration = min(1.0, timer.fireDate.timeIntervalSinceNow)
            runningTimer = NSTimer.scheduledTimerWithTimeInterval(duration, target: self, selector: "finish", userInfo: timer, repeats: false)
        }
    }

    func finish(nstimer:NSTimer) {
        let timer = nstimer.userInfo as Timer

        // update the gui countdown
        self.countDownDisplay?.text = "\(floor(timer.fireDate.timeIntervalSinceNow))"

        // remove timer
        timers = timers.filter { [=10=] !== timer }

        // schedule the next timer
        self.scheduleEarliestTimer()
    }
}

请注意,我使用 NSDate 来保持计时器关闭而不是持续时间,因为 "duration" 仅在已知起点时才有意义。如果想连续触发一串固定时长的操作,酌情修改。

由于您想要显示某种倒计时,您需要修改 NSTimer 以每秒触发一次直到适当的时间,每次触发更新倒计时。