2017-07-31 130 views
1

我有一个接受Textfield作为参数并基于标记的函数,数字发生变化;以下是代码示例减少多个if else语句的环化复杂度

func textFieldDidChange(_ textField: UITextField) { 
    if(textField.tag == 0){ 
     measureMentObject?.bloodPressureSystolic = myNumber 
    }else if(textField.tag == 1){ 
     measureMentObject?.bloodPressureDiastolic = myNumber 
    }else if(textField.tag == 2){ 
     measureMentObject?.heartRate = myNumber 
    }else if(textField.tag == 3){ 
     measureMentObject?.bodyTemperature = myNumber 
    }else if(textField.tag == 4){ 
     measureMentObject?.respitoryRate = myNumber 
    }else if(textField.tag == 5){ 
     measureMentObject?.o2Saturation = myNumber 
    }else if(textField.tag == 6){ 
     measureMentObject?.painScale = myNumber 
    }else if(textField.tag == 7){ 
     measureMentObject?.weight = myNumber 
    }else if(textField.tag == 8){ 
     measureMentObject?.po = myNumber 
    }else if(textField.tag == 13){ 
     measureMentObject?.gastricTube = myNumber 
    } 
} 

在这种情况下,如何降低环化复杂性?

+1

您可以使用开关 –

+0

使用标签创建枚举并使用开关。以确定标签:) –

+0

检查我的答案我已为您添加示例 –

回答

0

应该创建枚举创建更具可读性

enum SelectedTagTextField { 
    case bloodPressureSystolic = 0 
    case bloodPressureDiastolic = 1 
    ... 
    } 

并使用

switch(SelectedTagTextField(rawValue: textField.tag)) { 
    case SelectedTagTextField.bloodPressureSystolic : 
    .... And So on 
} 

希望它可以帮助

+0

FWIW - 您的伪代码应该可以是'切换SelectedTagTextField(rawValue:textField.tag){'更加明确 – AgRizzo

+0

@AgRizzo非常感谢您的建议。让我更新并检查它现在是否合适 –

+3

我不这么认为switch语句在这种情况下减少了循环复杂性,是的,它对于CC的可读性不错,不适用于CC –

1

如果你真的想摆脱if/else if块,一个方法是:

  • 子类的UITextField
  • 给它一个measureMentObjectKey: String属性

然后:

func textFieldDidChange(_ textField: UITextField) { 
    if let tf = textField as? MyTextField { 
     let tfKey = tf.measureMentObjectKey 
     measureMentObject.setValue(myNumber, forKey: tfKey) 
    } 
} 

(带有附加的错误检查,当然)。

+0

我会推荐子类'UITextField',但在通用办法。而不是给它一个'measureObject',我会给它一个闭包'onValueChanged'。然后,您可以使用正确的关闭来设置文本字段。我在我的所有项目中使用了这个,'UITextField' API是旧的,闭包可以真正改善它的使用。 – Sulthan

1

一种方式做到这一点是让一个Array一些二传手关闭:

class Measurement { 
    var bloodPressureSystolic : Float = 0.0 
    var bloodPressureDiastolic: Float = 0.0 
    var heartRate    : Float = 0.0 
    // ... 

    // Array of property setters 
    lazy var setters:[(Float) ->()] = [ 
    { [unowned self] in self.bloodPressureSystolic = $0 }, 
    { [unowned self] in self.bloodPressureDiastolic = $0 }, 
    { [unowned self] in self.heartRate    = $0 } 
    ] 
} 

使用例:

var bar = Measurement() 

print(bar.bloodPressureSystolic) 
// "0.0" 

bar.setters[0](5.0) 

print(bar.bloodPressureSystolic) 
// "5.0" 

注意,这只是移动了一个switch..caseif..else声明的复杂性选择一个Array成员。它可能会也可能不会更复杂,但如果Array以某种方式实现,它可以使用计算出的偏移量来查找成员。

,我可能会添加一个enum为了方便和文档目的:

// Convenience enum for property setter array 
    enum PropertyValues: Int { 
    case bloodPressureSystolic 
    case bloodPressureDiastolic 
    case heartRate 
    // ... 
    } 

你可以使用它像:

bar.setters[Measurement.PropertyValues.bloodPressureSystolic.rawValue](5.0) 

另一种方式来做到这一点是从NSObject继承和使用KVC

class Measurement:NSObject { 
    var bloodPressureSystolic: Float = 0.0 
} 

bar.setValue(10.0, forKey: "bloodPressureSystolic") 
// Example only, avoid forced unwrapped Optionals!!! 
print(bar.value(forKey: "bloodPressureSystolic") as! Float) 

你c然后使用相同的Array技巧,但使用String值将索引转换为键字符串。

+0

不错的解决方案!您也可以将setter更改为直接接受enum。 – Sealos

+0

当然,我首先保留了'enum',这样OP可以直接在代码中使用它。如果需要,将原始值转换为'enum'会很容易。 – ColGraff

0

简单地说,不要使用一个处理程序。使用倍数:

@IBAction 
func systolicBloodPressureTextFieldChanged(_ textField: UITextField) { 
    measureMentObject?.bloodPressureSystolic = myNumber 
} 

@IBAction 
func diastolicBloodPressureTextFieldChanged(_ textField: UITextField) { 
    measureMentObject?.bloodPressureDiastolic = myNumber 
} 

并将它们连接到.editingChanged操作。

这也可以让你避免这些邪恶的标签。