2017-07-31 65 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操作。

這也可以讓你避免這些邪惡的標籤。