避免多个 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"
}
我有一个类似的代码结构:
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"
}