如何验证 IBOutlet/var 是否为 nil?

3
我用Swift和Xcode 6.1.1编写了一个简单的应用程序。这个程序是一个简单的计算器,它可以正常工作,但我无法验证三个文本字段中的非nil输入。因此,如果用户将字段留空,然后点击“计算”,应用程序会崩溃。
该应用程序最初接受三个字符串输入。我编写了一个if语句来检查nil,但它不起作用 - 它只会传递到else。下面是与我的问题相关的代码块:
...
@IBOutlet var calcButton: UIBarButtonItem!
@IBOutlet var yearOneField: UITextField!
@IBOutlet var yearTwoField: UITextField!
@IBOutlet var yearThreeField: UITextField!
@IBOutlet var displayWindow: UILabel!

@IBAction func calcButtonTapped(sender: AnyObject) {

    if (yearOneField == nil) {

        displayWindow.text = ("Non-zero entries are not permitted. Please enter new values.")

    } else {

    let yearOne = yearOneField.text.toInt()
    let yearTwo = yearTwoField.text.toInt()
    let yearThree = yearThreeField.text.toInt()
    ...

我曾尝试评估IBOutlet是否为空,但这并没有起作用。作为Swift和Xcode的新手,希望更有经验的开发者能解答这个问题。谢谢。

3个回答

2
@IBOutlet为空的唯一可能是你忘记在Interface Builder中连接它们。通常你不需要检查这个问题,因为应用程序会崩溃并提示你解决这个问题。 toInt()函数返回一个可选的Int(也称为Int?),在使用之前必须进行解包。如果文本字段中的值不表示有效的Int,则toInt()将返回nil。如果使用toInt()转换"2.1"、"seven"和"",都会返回nil。我建议你使用可选绑定(if let)语法来检查转换是否为nil,并在结果不为nil时解包它。
if let yearOne = yearOneField.text.toInt() {
    if let yearTwo = yearTwoField.text.toInt() {
        if let yearThree = yearThreeField.text.toInt() {
            // yearOne, yearTwo, and yearThree are all valid Ints
            // so do the calculations
        }
    }
}

或者,如果您知道在无法将字段转换为 Int 时要使用默认值(如 0 ),则可以使用 nil合并运算符 ?? 取消包装结果,如下所示:

let yearOne = yearOneField.text.toInt() ?? 0
let yearTwo = yearTwoField.text.toInt() ?? 0
let yearThree = yearThreeField.text.toInt() ?? 0

谢谢@vacawama。我将尝试使用此方法来使我的代码更加智能化。 - maru37
如果异步函数在您导航离开视图后返回,会发生什么?如果您在完成处理程序中引用IBOutlet,它会是nil吗? - FateNuller
1
@FateNuller,如果你的闭包捕获了 self,那么视图控制器将一直存在,直到你的闭包完成并释放对 self 的强引用,或者如果你使用 [weak self] 来拥有一个对视图控制器的弱引用,那么当视图控制器被释放时,你的 self 将被设置为 nil,你将无法访问 @IBOutlets,因为它们已经不存在了。在任何情况下,你都不必担心这些输出将变成 nil - vacawama

1

这些文本字段本身永远不会是nil。它们在初始化期间被创建和分配,并且您从未将它们删除。

我认为您想检查它们的text属性是否包含任何文本,您可以像这样做:

更新至Swift 2:

if let text = yearOneField.text where !text.isEmpty {
    // perform the conversions
} else {
    // the text field is empty
}

您可以使用guard来避免嵌套:
guard let text = yearOneField.text where !text.isEmpty else {
    // the text field is empty
    return
}

// perform the conversions

我更喜欢使用guard语法,因为它更清晰地表达了理想结果。

谢谢你,Aaron。这正是我需要做的。 - maru37

0
你可以像处理普通 Optional 一样进行检查。
 guard let unwrapped = myLabel else {return}

或者像这样

 if myLabel == nil {
    //do stuff
 }

或者像这样:

 if let unwrappedLabel = myLabel {

 }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接