如何在Swift中重启或停止Timer而不破坏它?

时间:2017-09-04 08:15:01

标签: ios swift timer

我正在开发一个使用蓝牙设备的iOS应用程序,其中一个按钮与iPad通信。基本上我想要在按钮保持3秒或更长时间时发出帮助请求。

从我发现的所有文档中,我找不到使用 invalidate()方法停止计时器而不使其失效的方法。来自Apple's documentation

  

然后运行循环移除计时器(以及它对计时器的强引用),就在之前   无效()    方法返回或稍后返回。 无效后,计时器对象无法重复使用。

所以我的代码中的想法是,当按下按钮时,布尔 buttonWasHeld 设置为true并触发计时器。如果释放按钮,则 buttonWasHeld 设置为false,当计时器调用处理程序时,它知道按钮没有保持足够长的时间。然后,如果在3秒钟内再次按下该按钮,则计时器将再次设置。

问题是:按下每个按钮都会生成一个新的计时器,这意味着反复按下该按钮也会发出帮助请求。此外,所有这些计时器都由同一个变量处理,所以我不能区分它们。

有没有办法独特地告诉最后一个计时器是什么?还是一种暂停/停止它的模糊方法?

以下是控制此功能的代码段:

var buttonTimer: Timer?
var buttonWasHeld: Bool = false

func didUpdateModule() {
    // gpioListener takes a handler to be called whenever a button is
    // pressed or released. isPushed is a self-explanatory boolean.
    self.controller.gpioListener() { isPushed in
        if isPushed {
            self.buttonWasHeld = true
            self.buttonTimer = Timer.scheduledTimer(withTimeInterval: 3.0, repeats: false) { _ in
                if self.buttonWasHeld {
                    // Issue a help request
                    self.delegate?.notifyDevice(message: .HELP)
                    print("Asking for help")
                }
            }
            print("Button was pressed")
        }
        else {
            self.buttonWasHeld = false
            // Also tried "self.buttonTimer = nil" here. Didn't work
            print("Button was released")
        }
    }
}

1 个答案:

答案 0 :(得分:1)

像往常一样,答案很简单。

如果Timer被声明为 weak var ,而不仅仅是 var ,则只有弱实例化将被无效。所以代码应该是:

weak var buttonTimer: Timer?
var buttonWasHeld: Bool = false

func didUpdateModule () {
    (...)
        else {
            // This will only invalidate the current running timer,
            // not the whole variable :)
            self.buttonTimer.invalidate
            // I removed buttonWasHeld, it's not necessary anymore ;)
            print("Button was released")
        }
    }
}