避免多个 if 子句调用不同的方法

Avoid multiple if clauses to call different methods

我有一个类似的代码结构:

if !checkFirstName(firstName: firstNameField.text!)  {
   firstNameField.text = "foo"
   return false
}      
firstNameField.text = "bar"

if !checkLastName(lastName: lastNameField.text!)  {
   lastNameField.text = "foo"
   return false
}    
lastNameField.text = "bar"

...

这里的问题是我必须再做几次检查,但它们仅在函数名称和我正在处理的 UITextField 上有所不同。

我确实希望它们成为单个 for 循环或 map 的一部分,但似乎我无法通过使用 Selector() 使其工作,有点类似于以下:

let functionNames = ["FirstName", "LastName", ...]
let fields = ["FirstName": firstNameField, "LastName": lastNameField, ...]

...

for name in functionNames {
    let sel = Selector("check" + name + ":")

    if !view.perform(sel) {
       fields[name].text = "foo"
       return false 
    }

    fields[name].text = "bar"
    return true
}

Selector()在Swift中不推荐,即使它可能有效,我也想避免它。

我应该进一步研究使 Selector() 工作还是整个重复问题是架构问题?无论如何,我怎样才能避免它

我建议从您的视图中获取所有文本字段,然后继续使用通用函数。

(我没有编译下面的代码。)

func getAllTextFields() -> [UITextField] {
    var results:[UITextField] = []
    for subview in view.subviews {
        results += getAllTextFields(in: subview)
        if subview.isKind(of: UITextField.self) {
            if let textField = subview as? UITextField {
                results.append(textField)
            }
        }
    }
    return results
}


func YourFuncName() -> Bool {
  var allTextFields = getAllTextFields()
  var returnValue = true
  for textField in allTextFields {
    if !checkTextField(text: textField.text) {
        textField.text = “foo”
        returnValue = false
        break
    } else {
        textField.text = “bar”
    }
  }
  return returnValue

}

func checkTextField (text :String ) -> Bool {
//Your checking func body goes here
}

修改:我可以执行"perform selector"

函数是 Swift 中的第一个 class 对象,这意味着您也可以像传递变量一样传递它们。不要动态构建函数名称,而是将它们与元组中的 UITextField 相关联。

假设你有这些功能:

func check (firstName: String) -> Bool {
    // ...
}

func check (lastName: String) -> Bool {
    // ....
}

你可以这样循环:

// checks is an array of tuples. Each tuple has 2 components:
// a UITextField and a function which takes a String and return a Bool
let checks: [(field: UITextField, checker: (String) -> Bool)] = [
    (firstNameField, check(firstName:)),
    (lastNameField , check(lastName:))
]

for c in checks {
    guard c.checker(c.field.text!) else {
        c.field.text = "foo"
        return false
    }

    c.field.text = "bar"
}