2016-05-06 25 views
0

を作成するだから私はスウィフトに非常に新しいですし、このアプリを作るために、このチュートリアルを次されているhttps://www.youtube.com/watch?v=NJHsdjH2HdY電卓アプリ

これが最初の問題だった!currentNumber = currentNumber * 10 +フロート(sender.titleLabelの.text !!! currentNumber = currentNumber * 10 +フロート(!!のInt(sender.titleLabelの.text))

I:.toInt())コメントセクションで

は、男はにその行を変更するとスレッド1:EXC_BAD_INSTRUCTION(コード= EXC_I386_INVOP、サブコード= 0x0)

+2

これは、 "force unwrap"演算子( '!')を乱用しない理由です。あなたがそれを使うとき、あなたはコンパイラに「私が望むこの値はオプションであり、それは「無」であるかもしれないと理解していますが、そうではないと仮定しています。あなたがプログラムを実行して、実際には値が「nil」になると、プログラムは「私はあなたを信頼しました:」と嘘をついてしまい、究極的に自殺してしまいます。 – Alexander

+0

あなたの応答に感謝します。そのエラーを避けるために私は何を変更するのですか? – jimmythecat

+0

クラッシュを避けるためにnil coalescing演算子を使用してください: 'currentNumber = currentNumber * 10 + Float(Int(sender.titleLabel?.text ??" ")?0) ' – vacawama

答えて

3

コメントに記載されているように、常に 'クラッシュ演算子'(!)を使用しないでください。代わりにオプションの値を安全に処理する方法を学んでください。そして、あなたがそれらをアンラップ強制しようとしている - titleLabeltextまたはInt(...)いずれかがnilあるため

あなたのプログラムがクラッシュしています。これは、あなたのボタンにtitleLabelがないか、titleLabelのテキストがIntに変換できないことを意味する可能性があります。

解決策は、選択肢に遭遇したときに安全に対処することです。これを行うには多くの方法がありますが、通常は1つまたは複数のguardステートメントを使用します。これにより、値がある場合はオプションで安全にアンラップすることができます。そうでない場合は、大括弧内のコードが実行されます。これは、将来のコードnilでない場合、に依存する場合に便利です。例:

guard let buttonText = sender.titleLabel?.text else { 
    print("Sender didn't have either a titleLabel or text!") 
    return 
} 

guard let textAsInt = Int(buttonText) else { 
    print("Text wasn't convertible to an Int!") 
    return 
} 

currentNumber = currentNumber*10 + Float(textAsInt) 

ここで、クラッシュではなくprintメッセージが表示されます。したがって、何がうまくいかなかったのか、それを修正するために何ができるのか(修正が必要な場合)

また、あなたは、より簡潔なコードが必要な場合は、単一のguardにこれらのチェックの両方を統合し、あまり正確なエラーでした:

guard let buttonText = sender.titleLabel?.text, textAsInt = Int(buttonText) else { 
    print("Something went wrong when converting the button title to an Int!") 
    return 
} 

currentNumber = currentNumber*10 + Float(textAsInt) 

それとも、クロージャを好きなら、あなたがflatMapを使用することができます。

guard let i = sender.titleLabel?.text.flatMap({Int($0)}) else { 
    print("Something went wrong when converting the button title to an Int!") 
    return 
} 

currentNumber = currentNumber*10 + Float(i) 

flatMapオプションは最初はちょっと奇妙に見えますが、ボタンのtitleLabeltextIntに変換しようとしています。失敗した場合はnilguardが受け取る)を返し、そうでない場合はテキストの数値を返します。 @vacawama said in the commentsとして


、あなたもtitleLabeltextまたはInt(...)nilであることをイベントで0を使用するためにnilを合体演算子を使用することができます。

currentNumber = currentNumber * 10 + Float(Int(sender.titleLabel?.text ?? "") ?? 0) 

しかし、これができたことを心に留め予想外の動作につながります。私はあなたのロジックが非数値ボタン、例えば "+"ボタンのために実行されているので、あなたのプログラムがクラッシュしていると思われます。この場合、数字以外のボタンを押すたびに、あなたの番号に10を乗算します。最初に論理が数字ボタンでのみ呼び出されるようにする必要があります。

あなたのフルコードは表示されませんが、確かに言うのは難しいですが。安全にこのextensive Q&A on the subjectを参照してください、optionalsに対処する方法についての詳細情報については