【问题标题】:Need button to repeat the same function multiple times需要按钮多次重复相同的功能
【发布时间】:2018-06-18 23:37:27
【问题描述】:

代码的目的是在每次按下按钮时生成随机练习和代表次数(从数组中选择)。

但是,按钮只会在第一次按下时执行此操作,之后不会再次执行此操作。

问题:如何确保每次按下按钮时都会生成随机数量的代表和锻炼(从我的数组中选择)?

import UIKit

class ViewController: UIViewController

{

    var clickCount = 0

    let exercises = ["Push Ups", "Squats", "Burpees", "Sit Ups"]
    let reps = ["5", "6", "7", "8", "9", "10"]

    lazy var randomIndex1 = Int(arc4random() % UInt32(exercises.count))
    lazy var randomIndex2 = Int(arc4random() % UInt32(reps.count))

    @IBOutlet weak var countLabel: UILabel!
    @IBOutlet weak var excerciseType: UILabel!
    @IBOutlet weak var repVolume: UILabel!

    @IBAction func buttonPress(_ sender: UIButton) {

        clickCount+=1

        countLabel.text="You've Tapped \(clickCount) times"

        excerciseType.text="\(exercises[randomIndex1])"

        repVolume.text="\(reps[randomIndex2])"

    }

}

【问题讨论】:

  • 在您的按钮操作函数中移动随机索引。你现在拥有它的方式,它们在你第一次使用它们时被延迟初始化,并且数字不会改变。
  • 推荐。不要使用arc4random(),这可能会导致modulo bias,而是使用arc4random_uniform

标签: ios arrays swift button random


【解决方案1】:

您的 lazy 初始化变量在延迟初始化后不会更改其值。

使用 计算的 变量,而不是在每次访问时返回新值:

var randomIndex1 : Int {
    return Int(arc4random_uniform(UInt32(exercises.count))
}

var randomIndex2 : Int {
    return Int(arc4random_uniform(UInt32(reps.count))
}

代码使用更合适的APIarc4random_uniform

【讨论】:

  • 虽然这可以工作但不是必需的。只需将变量设为函数的本地变量,而不是类实例。如果在函数之外不需要这些值,则不要使它们可用,如果它们是可用的,那么每次访问它们时它们都会有所不同,这有点毫无意义。
  • 不能,会?。我只是想尽可能接近这个问题。
  • 是的,它工作得很好,而且肯定有合适的时候。例如,它允许更改 randomIndex1 和 randomIndex2 的计算方法,而不会影响使用它的任何东西。所以它确实有优势,但如果使用它的函数是孤立的,那么我认为最好将尽可能多的相关代码放在一起以提高可读性。
【解决方案2】:

通过将变量放入buttonPress 方法中来生成一个新值

所以,我会删除这两行

   lazy var randomIndex1 = Int(arc4random() % UInt32(exercises.count))
   lazy var randomIndex2 = Int(arc4random() % UInt32(reps.count))

并在 buttonPress 中设置这些值

 @IBAction func buttonPress(_ sender: UIButton) {

   clickCount+=1
   let randomIndex1 = Int(arc4random() % UInt32(exercises.count))
   let randomIndex2 = Int(arc4random() % UInt32(reps.count))

   countLabel.text="You've Tapped \(clickCount) times"

   excerciseType.text="\(exercises[randomIndex1])"

   repVolume.text="\(reps[randomIndex2])"

 }

现在它应该在每次按下按钮时生成一个新的随机值。正如 Leo 在 cmets 中所说,由于我们每次都在重新生成它们,它们应该是 let 而不是 var

注意

我最初提到了一些关于惰性变量的内容,因为这里似乎不需要它们。因此,如果您阅读 cmets 并想知道人们在谈论什么;这是我最初所说的,这并不能真正帮助 OP 解决问题并且不清楚;所以我把它移到这个注释:

一些事情:

  • lazy var 实际上是一个常量(或者至少在很多地方它都被视为一个常量)

【讨论】:

  • 你能引用“惰性变量实际上是一个常量”吗?
  • 惰性 var 不是常量。所有惰性 var 都是一个 var,它的初始值在实际需要之前不会计算。很多人将它们视为常量,但这并没有以任何方式强制执行,也不是它们的设计方式。在函数 randomIndex1 和 randomIndex 2 内部也可以定义为 let 而不是 var 因为它们永远不会发生变异。除此之外测试是正确的。
  • hmm.. 这是最近苹果文档中的讨论。 developer.apple.com/library/content/documentation/Swift/… 让我也想想如何改写它。 OP 使用惰性并不是真正的问题,但我只是在评论它。也许我会在我的回答中去掉那部分。
  • 是的,@UpholderOfTruth 说的比我说的好。当我们不想在使用之前创建事物时,我们使用“懒惰”,并且在许多情况下它是一个常量,因为不允许有“懒惰让”
  • 顺便说一句,最好使用 arc4random_uniform。 Int(arc4random_uniform(UInt32(exercises.count)))
【解决方案3】:

要使您的随机数发生器可重复使用,您应该将其移至一个新函数中。为了这个答案,我将其称为randomize()。你可以这样实现:

import UIKit

class ViewController: UIViewController {

  var clickCount = 0

  let exercises = ["Push Ups", "Squats", "Burpees", "Sit Ups"]
  let reps = ["5", "6", "7", "8", "9", "10"]

  lazy var randomIndex1 = Int(arc4random() % UInt32(exercises.count))
  lazy var randomIndex2 = Int(arc4random() % UInt32(reps.count))

  @IBOutlet weak var countLabel: UILabel!
  @IBOutlet weak var excerciseType: UILabel!
  @IBOutlet weak var repVolume: UILabel!

  @IBAction func buttonPress(_ sender: UIButton) {
    clickCount+=1
    countLabel.text="You've Tapped \(clickCount) times"
    self.randomize()
  }

  func randomize() {
    self.randomIndex1 = Int(arc4random() % UInt32(exercises.count))
    self.randomIndex2 = Int(arc4random() % UInt32(reps.count))
    self.excerciseType.text="\(exercises[randomIndex1])"
    self.repVolume.text="\(reps[randomIndex2])"
  }

}

【讨论】:

  • 它不需要是一个单独的函数,如果只需要在单击按钮时使用它但不会造成伤害。然而真正的问题是 randomIndex1 和 randomIndex2 不需要是类变量,但可以是函数的本地变量(除非它们在其他地方也需要)
  • @UpholderOfTruth 你是对的。我想这只是一种选择。计算出的属性答案最终是最好的 - 我自己投票赞成。
  • 我刚刚评论了一个计算出来的,我实际上会沿着函数本地变量的路线走(这就是我赞成这个答案的原因)。
  • 所以和这个答案一样,但只是将所有代码保留在按钮选择器中?我想我只是想他可能想从其他地方调用代码,但我想问题中从未说明过。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-03-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-11-29
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多