Noch ein Problem mit Optionals

Diese Seite verwendet Cookies. Durch die Nutzung unserer Seite erklären Sie sich damit einverstanden, dass wir Cookies setzen. Weitere Informationen

  • Noch ein Problem mit Optionals

    Hallo, sorry, dass ich ein ähnliches Problem poste. Ich versuche mich gerade in jeglicher Hinsicht an Optionals. Das untenstehende Program hat super funktioniert. Jetzt habe ich die shouldChangeCharactersIn method implementiert mit delegate protokoll. Das Program ist gecrasht mit der Fehlermeldung :"Thread 1: Fatal error: Unexpectedly found nil while unwrapping an Optional value". Hat jemand eine Idee, was ich hier übersehen habe?? Danke.

    Quellcode

    1. import UIKit
    2. class ViewController: UIViewController, UITextFieldDelegate {
    3. //text input fields
    4. @IBOutlet weak var kgField: UITextField!
    5. @IBOutlet weak var poundsField: UITextField!
    6. @IBOutlet weak var litersField: UITextField!
    7. @IBOutlet weak var gallonsField: UITextField!
    8. @IBOutlet weak var kmField: UITextField!
    9. @IBOutlet weak var milesField: UITextField!
    10. //result text field
    11. @IBOutlet weak var poundsResult: UILabel!
    12. @IBOutlet weak var kgResult: UILabel!
    13. @IBOutlet weak var gallonsResult: UILabel!
    14. @IBOutlet weak var litersResult: UILabel!
    15. @IBOutlet weak var milesResult: UILabel!
    16. @IBOutlet weak var kmResult: UILabel!
    17. override func viewDidLoad() {
    18. super.viewDidLoad()
    19. kgField.delegate = self
    20. gallonsField.delegate = self
    21. poundsField.delegate = self
    22. kmField.delegate = self
    23. milesField.delegate = self
    24. litersField.delegate = self
    25. }
    26. //making it so only the characters in the string are allowed in the textfields
    27. func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool
    28. {
    29. let allowedCharacters = "0.123456789"
    30. let allowedCharacterSet = CharacterSet(charactersIn: allowedCharacters)
    31. let typedCharacterSet = CharacterSet(charactersIn: string)
    32. return allowedCharacterSet.isSuperset(of: typedCharacterSet)
    33. }
    34. //conversion functions for each page
    35. @IBAction func milesToKM(_ sender: Any) {
    36. kmResult.text = "\(doConversion(conversionFactor: 1.6093, inputField: milesField))"
    37. }
    38. @IBAction func kmToMiles(_ sender: Any) {
    39. milesResult.text = "\(doConversion(conversionFactor: 0.62, inputField: kmField))"
    40. }
    41. @IBAction func litersToGallons(_ sender: Any) {
    42. gallonsResult.text = "\(doConversion(conversionFactor: 0.26, inputField: litersField))"
    43. }
    44. @IBAction func gallonsToLiters(_ sender: Any) {
    45. litersResult.text = "\(doConversion(conversionFactor: 3.78, inputField: gallonsField))"
    46. }
    47. @IBAction func kgToPounds(_ sender: Any) {
    48. poundsResult.text = "\(doConversion(conversionFactor: 2.2, inputField: kgField))"
    49. }
    50. @IBAction func poundsToKG(_ sender: Any) {
    51. kgResult.text = "\(doConversion(conversionFactor: 0.45, inputField: poundsField))"
    52. }
    53. var inputDouble = Double()
    54. var outputValue = Double()
    55. //conversion math function
    56. func doConversion(conversionFactor : Double, inputField : UITextField) -> Double
    57. {
    58. if Double(inputField.text!) != nil {
    59. let inputDouble = Double(inputField.text!)!
    60. outputValue = inputDouble * conversionFactor
    61. }
    62. else {
    63. outputValue = 0
    64. }
    65. return outputValue
    66. }
    67. override func didReceiveMemoryWarning() {
    68. super.didReceiveMemoryWarning()
    69. // Dispose of any resources that can be recreated.
    70. }
    71. }
    Alles anzeigen
  • CreativeCoder schrieb:

    Das Program ist gecrasht mit der Fehlermeldung :"Thread 1: Fatal error: Unexpectedly found nil while unwrapping an Optional value". Hat jemand eine Idee, was ich hier übersehen habe??

    Ja. Uns mitzuteilen was der Debugger sagt in welcher Zeile der Crash passiert. ;)

    Lern selbständig debuggen!^^

    Beim Blick über den Code würde ich hier ansetzen:

    Quellcode

    1. if Double(inputField.text!) != nil {
    2. let inputDouble = Double(inputField.text!)!
    Einfach nur wegen der unsäglichen !-Orgie.
    Das iPhone sagt: "Zum Antworten streichen". Wie? Echt Jetzt? Muß ich erst die Wohnung streichen!?
  • Hm, ich habe hier schon einiges versucht. Ist es das Double(inputField.text!)!. ?? Komischerweise klappt das gleiche Program, wenn ich die delegate UITextFIeld Methode nicht implementiere. Das macht mich stutzig. Und ja, das mit dem selbstaendig debuggen steht ganz oben auf meiner Liste:)
  • Versuche es damit:
    Wenn ich es recht sehe, soll im Fehlerfalle immer 0.0 zurückgeben werden, oder?

    Quellcode

    1. var outputDouble = 0.0
    2. func doConversion(conversionFactor : Double, inputField : UITextField) -> Double
    3. {
    4. if let text = inputField.text {
    5. outputDouble = Double(text) ?? 0.0
    6. outputDouble *= conversionFactor
    7. }
    8. return outputDouble
    9. }
  • @ Matz: Hier ist der Code, der funktioniert (ohne Delegate Method)

    Quellcode

    1. import UIKit
    2. class ViewController: UIViewController {
    3. @IBOutlet weak var kgField: UITextField!
    4. @IBOutlet weak var poundsField: UITextField!
    5. @IBOutlet weak var litersField: UITextField!
    6. @IBOutlet weak var gallonsField: UITextField!
    7. @IBOutlet weak var kmField: UITextField!
    8. @IBOutlet weak var milesField: UITextField!
    9. @IBOutlet weak var poundsResult: UILabel!
    10. @IBOutlet weak var kgResult: UILabel!
    11. @IBOutlet weak var gallonsResult: UILabel!
    12. @IBOutlet weak var litersResult: UILabel!
    13. @IBOutlet weak var milesResult: UILabel!
    14. @IBOutlet weak var kmResult: UILabel!
    15. //conversion functions for each page
    16. @IBAction func milesToKM(_ sender: Any) {
    17. kmResult.text = "\(doConversion(conversionFactor: 1.6, inputField: milesField))"
    18. }
    19. @IBAction func kmToMiles(_ sender: Any) {
    20. milesResult.text = "\(doConversion(conversionFactor: 0.62, inputField: kmField))"
    21. }
    22. @IBAction func litersToGallons(_ sender: Any) {
    23. gallonsResult.text = "\(doConversion(conversionFactor: 0.26, inputField: litersField))"
    24. }
    25. @IBAction func gallonsToLiters(_ sender: Any) {
    26. litersResult.text = "\(doConversion(conversionFactor: 3.78, inputField: gallonsField))"
    27. }
    28. @IBAction func kgToPounds(_ sender: Any) {
    29. poundsResult.text = "\(doConversion(conversionFactor: 2.2, inputField: kgField))"
    30. }
    31. @IBAction func poundsToKG(_ sender: Any) {
    32. kgResult.text = "\(doConversion(conversionFactor: 0.45, inputField: poundsField))"
    33. }
    34. var inputDouble = Double()
    35. var outputValue = Double()
    36. //conversion math function
    37. func doConversion(conversionFactor : Double, inputField : UITextField) -> Double
    38. {
    39. if Double(inputField.text!) != nil {
    40. let inputDouble = Double(inputField.text!)!
    41. outputValue = inputDouble * conversionFactor
    42. }
    43. else {
    44. outputValue = 0
    45. }
    46. return outputValue
    47. }
    48. override func viewDidLoad() {
    49. super.viewDidLoad()
    50. // Do any additional setup after loading the view, typically from a nib.
    51. }
    52. override func didReceiveMemoryWarning() {
    53. super.didReceiveMemoryWarning()
    54. // Dispose of any resources that can be recreated.
    55. }
    56. }
    Alles anzeigen
  • CreativeCoder schrieb:

    @ Matz: Hier ist der Code, der funktioniert (ohne Delegate Method)

    Quellcode

    1. import UIKit
    2. class ViewController: UIViewController {
    3. ....
    4. var inputDouble = Double()
    5. var outputValue = Double()
    6. //conversion math function
    7. func doConversion(conversionFactor : Double, inputField : UITextField) -> Double
    8. {
    9. if Double(inputField.text!) != nil {
    10. let inputDouble = Double(inputField.text!)!
    11. outputValue = inputDouble * conversionFactor
    12. }
    13. else {
    14. outputValue = 0
    15. }
    16. return outputValue
    17. }
    18. ....
    19. }
    Alles anzeigen
    Mir fällt hier auf, dass deine Methode den Wert einer Variablen zurückgibt, die außerhalb der Methode deklariert ist. Das Ergibt nicht viel Sinn.
  • Uzhul schrieb:

    Michael schrieb:

    Mir fällt hier auf, dass deine Methode den Wert einer Variablen zurückgibt, die außerhalb der Methode deklariert ist. Das Ergibt nicht viel Sinn.
    Das, und ich würde die Funktion auf jeden Fall durch meine Variante ersetzen, denn diese !-Orgie geht garantiert schief. Die "outputValue-Variable" natürlich dann in der Funktion definieren.

    Wenn man schon mit dem nil coalescing operator, aka ?? arbeitet, kann man das auch in einen Einzeiler zusammenfassen, ganz ohne Zwischenvariable:

    Quellcode

    1. func doConversion(conversionFactor: Double, inputField: UITextField) -> Double {
    2. return (Double(inputField.text ?? "") ?? 0.0) * conversionFactor
    3. }
    ;)
    Das iPhone sagt: "Zum Antworten streichen". Wie? Echt Jetzt? Muß ich erst die Wohnung streichen!?
  • torquato schrieb:

    Wenn man schon mit dem nil coalescing operator, aka ?? arbeitet, kann man das auch in einen Einzeiler zusammenfassen, ganz ohne Zwischenvariable:

    Quellcode

    1. func doConversion(conversionFactor: Double, inputField: UITextField) -> Double {
    2. return (Double(inputField.text ?? "") ?? 0.0) * conversionFactor
    3. }
    ;)
    Das ist jedoch, ausgehend vom ursprünglichen Code, nicht das Gleiche. Auch wenn der Sinn, der außerhalb definierten Variable DoubleValue (noch?) nicht zu erkennen ist. :)

    Ich würde ohnehin sagen, daß sich die ganzen Outlets in ein Outlet-Array, sowie die ganzen Actions zusammenfassen lassen.