【问题标题】:How to restart or stop a Timer in Swift without destroying it?如何在 Swift 中重新启动或停止 Timer 而不会破坏它?
【发布时间】:2017-09-04 08:15:01
【问题描述】:

我正在使用带有与 iPad 通信的按钮的蓝牙设备开发 iOS 应用程序。基本上我希望在按住按钮 3 秒或更长时间时发出帮助请求。

从我找到的所有文档中,我找不到使用 invalidate() 方法在不使其失效的情况下停止 Timer 的方法。来自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")
        }
    }
}

【问题讨论】:

  • How to stop NSTimer的可能重复
  • 解决方案正是我想要避免的,使计时器无效。这将使这个计时器无法使用。
  • 每次你想创建一个新的计时器时,检查存储在buttonTimer中的计时器是否已经使用isValid失效。如果已经失效,则创建一个新的,否则使用当前的。
  • 我也试过了,@Sweeper ...不太成功

标签: ios swift timer


【解决方案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")
        }
    }
}

【讨论】:

  • 这正是我想要的。其他解决方案不太正确。感谢您发布此信息 - 我只需要“弱”。 +1
最近更新 更多