如何在不破坏的情况下重启或停止Swift中的Timer?
问题描述:
我正在开发一个iOS应用程序,使用蓝牙设备和一个与iPad通信的按钮。基本上我希望当按钮保持3秒或更长时间时发出帮助请求。如何在不破坏的情况下重启或停止Swift中的Timer?
从我发现的所有文档中,我找不到使其无效的方法来停止定时器,并使用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")
}
}
}
答
像往常一样,答案是很简单的。
如果计时器被声明为弱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")
}
}
}
的可能的复制[如何停止的NSTimer(https://stackoverflow.com/questions/3509012/how-to-stop-nstimer) – the4kman
有什么解决办法我正在寻找避免,使计时器无效。它会使这个定时器不可用。 –
每次你想创建一个新的定时器,检查存储在'buttonTimer'中的定时器是否已经使用'isValid'失效。如果它已经失效,则创建一个新的,否则使用当前的。 – Sweeper