【问题标题】:How do I uninitialize a variable reference in Swift如何在 Swift 中取消初始化变量引用
【发布时间】:2015-03-09 12:52:50
【问题描述】:

我有一个接受发送者的@IBAction 函数:UIButton!作为参数。

@IBAction func buttonPress(sender: UIButton!)

在函数的某个时刻,我将发送者复制到另一个变量,该变量之前声明为 UIButton()

anotherVar = sender

我知道这是对原始发件人的引用,因为 UIButton 是一个类

然而,在代码的某个点,我想打破对发件人的引用,并将 anotherVar “重置”为普通的 UIButton()。我该怎么做?

编辑: 我觉得我应该扩展我正在做的事情,也许我做错了……

我有八个按钮,它们都调用同一个名为 buttonPress() 的 @IBAction 函数。这个想法是让用户点击一个按钮,查看一个图像,然后点击另一个按钮(其余七个按钮)以找到匹配的图像。当 buttonPress() 被调用时,代码: 1. 检查这是否是第一个被点击的按钮 - 如果是,则显示按钮图像,然后将 sender 分配给 anotherVar; - 如果是第二个按钮被按下(即之前单击了另一个按钮),代码运行匹配以将发送者的图像与上面设置的 anotherVar 的图像进行比较 2. 如果有匹配,我会“锁定”按钮,这样如果用户再次点击按钮,匹配逻辑就不会被执行 3. 如果没有匹配,我想“清除” anotherVar 为另一个匹配任务做好准备。我不想“锁定”按钮,因为可能仍需要单击同一个按钮。

这是完整的代码:

@IBAction func buttonPress(sender: UIButton!) {

    var buttonImage = UIImage()
    buttonImage = UIImage(named: listOfImages[sender.tag])!

    if (!imageIsDone[sender.tag] && (sender.tag != buttonToCompare.tag)) {
        // Only execute button logic if match for image not already found and the user isn't tapping the same image
        if (imageAwaitingCheck) {
            // User has made their first image selection, do matching logic on image clicked
            sender.setImage(buttonImage, forState: .Normal)
            if (sender.currentImage == buttonToCompare.currentImage) {
                // Tapped image macthes previously clicked image
                println("Match")

                // "Lock" the buttons as they've been matched
                imageIsDone[sender.tag] = true
                imageIsDone[buttonToCompare.tag] = true
                imageAwaitingCheck = false  
            }
            else {
                // Tapped image does not match previously clicked image
                println("No match")
                imageAwaitingCheck = false
                buttonToCompare.tag = 100 
                // ********ERROR IS HERE*********I forced this so that
                // (sender.tag != buttonToCompare.tag) is true above when
                // the user taps on the first button again after no match is found.
                // However, this is a REFERENCE to the original sender and sets the
                // button tag to 100 which causes the condition to fail and hence
                // tapping button 1, then button 2, no match, then clicking button 1
                // again doesn't execute any of this logic
            }
        }
        else {
            // User has selected this as the first image, simply show it
            sender.setImage(buttonImage, forState: .Normal)
            imageAwaitingCheck = true
            buttonToCompare = sender // I am copying sender to buttonToCompare. Ideally this would create a copy but because UIButton is a class, this is creating a buttonToCompare as a reference
        }

    }

}

【问题讨论】:

  • 我不确定我理解是什么让sender 不是“普通的普通 UIButton”但是...如果您在分配之前将 anotherVar 的先前值保存在其他变量中会怎样sender 然后在你想“重置”时恢复它。

标签: ios swift uibutton


【解决方案1】:

只要将anotherVar 分配为var,而不是let,就可以在完成sender 后执行以下操作:

anotherVar = UIButton()

这将“覆盖”anotherVar 的先前值并将其“重置”为 UIButton 的新实例。

但是,如果您访问 anotherVar 的唯一位置是此函数,您可能根本不需要执行此操作 - 只要您调用 anotherVar = sender,它也将替换对上一个按钮的引用使用新的发件人按钮。


要在编辑后实现您所描述的内容,您实际上不需要进行大量更改。在这个 if 语句中:if (sender.currentImage == buttonToCompare.currentImage) 在最后添加 buttonToCompare = UIButton()。在else-statement 中,做同样的事情而不是改变它的标签。

或者,如果您希望复制发件人,您可以这样做:

let archivedData = NSKeyedArchiver.archivedDataWithRootObject(button)
let buttonCopy = NSKeyedUnarchiver.unarchiveObjectWithData(archivedData)

【讨论】:

  • anotherVar 在我的代码中确实是 buttonToCompare。我已将其声明为 var。当我将它设置为 UIButton() 时,它的标签默认为“0”,这会导致代码顶部的 IF 条件在点击带有标签 0 的按钮时失败(sender.tag != buttonToCompare.tag)。我想一个选择是从 1 而不是 0 开始我的按钮标签,但还有其他方法吗?
  • @zeeshan 在这种情况下,您应该使用 tag = 0 更改按钮的标签:) 请查看更新后的答案
  • 谢谢,这有效,我采用了将违规按钮的标签从 0 更改为其他数字的方法!
猜你喜欢
  • 1970-01-01
  • 2017-03-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-03-12
  • 1970-01-01
  • 2017-05-01
相关资源
最近更新 更多