【问题标题】:Closure argument becomes nil闭包参数变为 nil
【发布时间】:2015-10-27 14:17:02
【问题描述】:

我在尝试验证用户输入时遇到了一个奇怪的问题。我正在使用表单框架的包装器,我希望它能够验证用户输入。 问题是,当我使用 userValue 参数调用闭包时,它最终是 nil 并且所有检查都返回 false:

class FormRowWrap {
    var tag: String
    var row: AnyObject
    var verification: (value: Any?) -> Bool
    init(tag: String, row:AnyObject, verification:(Any?) -> Bool) {
        self.tag = tag
        self.row = row
        self.verification = verification
    }
}

class InsertViewController: FormViewController {

let rows = [
    {
        let tag = "Fuel Name"
        let row = FormRowWrap(tag: tag,
            row:TextRow(tag) {
                $0.title = tag
                //                $0.value = last known user default
            },
            verification:({(value: Any?) -> Bool in
                if let thing = value as? String { 
//^----- the value in a **breakpoint here is nil**
//
                    if !thing.isEmpty {
                        return true
                    }
                }
                return false
            }))
        return row
        }() as FormRowWrap,

    {
        let tag = "Price"
        let row = FormRowWrap(tag: tag,

...

func formValuesAreValid(values: [String: Any?]) -> Bool {
    var result = false
    for rowWrap in self.rows {
        let userValue = values[rowWrap.tag]
        print("userValue      \(userValue) forTag: \(values[rowWrap.tag])")
// ^---- this prints userValue      **Optional(Optional("Ghh")) forTag: Optional(Optional("Ghh"))**
        let entryIsValid = rowWrap.verification(value: userValue)

        if (!entryIsValid) {
            result = false
            return result
        }
    }
    result = true
    return result
}

如果我运行 rowWrap.verification(value:"test") 它会返回 true,所以我认为这是关于正确展开值的问题。

【问题讨论】:

    标签: ios swift2


    【解决方案1】:

    您的函数需要一个 Optional,但 userValue 是另一个 Optional 中的 Optional:

    可选(可选(“Ghh”))

    所以当你强行打开它时

    let entryIsValid = rowWrap.verification(value: userValue!)
    

    实际发生的情况是您打开 第一层 并取回一个 Optional:

    可选的(“Ghh”)

    这是你的函数签名

    (value: Any?) -> Bool
    

    需要。

    关于为什么它被包裹了两次:

    formValuesAreValid(values: [String: Any?])

    values 字典中的值是 Optionals,然后当你访问字典时:

    let userValue = values[rowWrap.tag]
    

    你得到另一个 Optional - 因为访问字典总是返回一个 Optional,所以在这种情况下 values[rowWrap.tag] 返回一个“Optional Optional”。

    然后你在其他地方打开包装,一旦你认为你会得到值 if let thing = value as? String,但你得到的是内部 Optional,你的下一次检查失败。

    【讨论】:

    • 感谢您的回答!
    【解决方案2】:

    找到了一种通过强制解开“userValue”使其工作的方法:

    让 entryIsValid = rowWrap.verification(value: userValue!)

    我仍然不明白为什么这有效,以及为什么它不适用于包装为可选的参数。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-02-14
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多