修正日: 07/10/19
練習問題12
解答編
解答編です。といっても難しいことはそれほどなかったと思いますが。まずデバッグをする上では「アクティブなビルド設定」をDebugにしてからビルドする、ということを忘れないでください。ブレークポイントで止まらない、バグだ!と焦る前にビルド設定を確認しましょう。
今回仕込んだバグは以下の三点です。
- BMI計算の結果がおかしい
- 身長の値が起動するたびにもとに戻ってしまう
- BMIが18より低い時Dockのアイコンが青に変わるはずが変わらない
全てチェックしましたか?見落としがあったらもう一度調べなおしてください。公開する前にこのようにバグが無いかをいろいろチェックするのは結構大変な作業です。知合いに試しに使ってもらうというのも大切です。また公開後にたまにバグの指摘があるので、そういうときはなるべく早く修正するように努力しましょう。
また当然のことですが、プログラムの構造についてある程度理解していないとうまくデバッグすることができません。上記2のバグの原因を調べるために、例えばBMIの計算をする部分にブレークポイントを仕掛けても意味が無い、ということは分かると思います。正しく値が保存されているか、保存された値が正しく読み込まれているか、「saveUserDefaults」と「loadUserDefaults」をチェックしなければなりません。
ということでまず2の解説。保存が正しく行われているかをチェックするためにまず「saveUserDefaults」を見てみると、特に問題は無さそうです。「loadUserDefaults」の方にブレークポイントを仕掛けて動作をチェックしてみましょう。何度実行しても
height=[aDefault floatForKey:@"height"];
のデータの読み込みには行かず、
height=[heightField floatValue];
に行ってしまうはずです。どうもifの分岐に問題があるようです・・・
原因がわかりましたか?
ちなみに初期設定フォルダに入っている「learnCocoa.sekn.CalcBmi.plist」という初期設定ファイルをダブルクリックすると、「Property List Editor」というアプリで初期設定の保存内容を覗くことができます。
これを覗けば身長が正しく保存されているか、それとも保存に失敗しているのかを確認することができます。
1のBMIの計算がおかしいというバグは見つけやすいと思いますので解説は省略。
- (IBAction)changeBMI:(id)sender;
- (IBAction)changeHeight:(id)sender;
- (IBAction)changeWeight:(id)sender;
あたりにブレークポイントを置いて、計算の様子を順番にチェックしてください。
3のアイコンの問題は当然「setDockIcon」メソッドを調べます。ステップオーバーで一行ずつ実行していくと・・・
青アイコンの読み込みの所へは正しく進んでいます。ところが・・・
読み込んだNSImageへのポインタである変数「anIcon」が「0x0」になっています。「0x0」とは16進数で0のこと、NSImageのインスタンスが「無い」ということです(例えば0x123なら16進数で123、10進数では291のことです。ただしポインタの値はメモリのアドレスであり10進数に戻しても意味はありません。「0x0の時はオブジェクトが無い」ということだけ覚えておいてください)。つまり
anIcon=[NSImage imageNamed:@"blue.png"];
でアイコンファイルをうまく読み込めなかった、ということです。なぜ読み込めなかったのかは自分で調べてみてください。
この辺で解答編は終わります。効率よくデバッグするには、解説しにくいノウハウや、どこに問題があるかを見つける勘などいろいろな要素があります。いろいろなアプリを作って、たくさんデバッグをしてみるのが一番です。
一通りそれらしいアプリケーションが完成し、デバッグの方法も学んだので、しばらく続いてきた「CalcBMIみたいなのを作ってみよう! 」シリーズはここまでで終わりにします。長々とやってはきたものの、プログラミングの工程そのものはそれほど多くなく、簡単なものならかなり手軽に作れるということがわかっていただけたのではないでしょうか?
次回からは「バインディング」を使ってもっと楽にプログラムを書く手法を紹介したいと思います。