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

时间:2018-01-22 03:54:11

标签: ios swift architecture selector

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

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
}
在Swift中不建议使用

Selector(),即使它可能有效,我也要避免使用它。

我是否应该进一步研究使Selector()工作还是整个复制问题是一个架构问题?在任何情况下,我怎么能避免它

2 个答案:

答案 0 :(得分:1)

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

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

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
}

修改:我可以执行“执行选择器”

enter image description here

答案 1 :(得分:1)

函数是Swift中的第一类对象,这意味着你也可以像变量一样传递它们。不是动态地构建函数名,而是将它们与元组中的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"
}