应用程序在计时器后崩溃而不是重新启用按钮

App crashes after the timer Instead of re-enabling button

我是 XCode 的新手,我们将不胜感激。

按下按钮时,按钮应该被禁用并且应该显示一个随机数并触发一个计时器。一旦计时器完成,按钮将再次启用。

这是按钮代码:

@IBAction func MarketButton(_ sender: UIButton) {
    let t = Int(arc4random_uniform(10))
    MarketLabel.text = String (t)
    let timer = Timer.scheduledTimer(timeInterval: 10, target: self, selector: #selector(MarketViewController.MarketButton), userInfo: nil, repeats: false)
    sender.isEnabled = !(timer.isValid )

你这里有几个问题:

导致崩溃的原因是 MarketButton 要求您将 UIButton 作为参数传递,而计时器在触发时不会执行此操作。您可以通过 scheduledTimer 的 userInfo 参数传入按钮来完成此操作。这是关于如何做 that.

的堆栈溢出 post

但是,即使在您执行此操作之后,仍然无法正常工作。 您需要制作一个方法来处理计时器完成的时间。

类似于:

func enableButton() {
    yourButton.isEnabled = true
}

然后将其作为选择器而不是 MarketButton 方法。

像这样:

let timer = Timer.scheduledTimer(timeInterval: 10, target: self, selector: #selector(enableButton), userInfo: nil, repeats: false)

通过将 "MarketButton" 作为计时器的选择器,您将导致无限循环。计时器完成后,它会调用该方法,然后触发另一个计时器,依此类推。

另一个问题是这两行代码:

let timer = Timer.scheduledTimer(timeInterval: 10, target: self, selector: #selector(MarketViewController.MarketButton), userInfo: nil, repeats: false)
sender.isEnabled = !(timer.isValid )

在这种情况下,计时器几乎总是有效的,因为您只是设置了它。所以 !(timer.isValid) 基本上总是 return false。但是,如果您听从我的建议并触发不同的方法而不是 MarketButton,那么这将不是问题。

还有一个旁注,在命名函数时你不应该将它们大写所以 MarketButton 应该是 marketButton.

我建议尝试根据我提供给您的信息找到解决方案。如果您有任何问题,请告诉我,欢迎来到 stack overflow!

欢迎来到 Stack Overflow。让我向您介绍一下您的代码在按下按钮后的那一刻正在做什么。

  1. 创建一个介于 0 和 10 之间的随机数
  2. 将数字放入标签
  3. 安排计时器启动相同的功能
  4. 如果计时器有效,它将禁用按钮。如果计时器无效,它将启用按钮。

然而,在计时器触发后,它会调用相同的函数。这一次它不会有相同的参数。在第一个 运行 中,按钮将自己传递给第一个参数的函数。这次,计时器将成为第一个参数。不幸的是,这是因为选择器 API 类型不安全。因此,一旦触发计时器,就会发生以下情况:

  1. 函数被调用
  2. 生成一个随机数并写入您的标签
  3. 新的计时器已启动
  4. objective C运行时间,也就是运行你的iOS应用程序,试图找到它isEnabled属性不会在您的计时器上找到,它会崩溃。

因此,您的计时器调用@boidkan 建议的另一个函数至关重要。我建议这样:

class TimebombViewController {
    @IBOutlet weak var timerLabel: UILabel!
    @IBOutlet weak var startButton: UIButton!

    var timer: Timer?
    @IBAction startButtonPressed(_ sender:UIButton){
        timerLabel.text = Int(arc4random_uniform(10)).description
        timer = Timer.scheduledTimer(timeInterval: 10, target: self, selector: #selector(timerFired), userInfo: nil, repeats: false)
        refreshButtonState()
    }

    @objc timerFired(_ timer:Timer){
        timer = nil
        refreshButtonState()
    }

    func refreshButtonState(){
        startButton.isEnabled = !(timer?.isValid ?? false)
    }

}