プログラミングとデバッグ作業の基本
入力と出力がある
プログラムは、入力と出力があります。そしてその間に処理、があります。今回のカウンタは、ボタンを押すという操作が入力、数字の増減が処理、数値の変化とその表示反映が出力です。
時計のように、一定時間ごとに表示が変化するものは、一見すると入力がないように見えますが、”時間の経過”という入力があります。
プログラムは、かならず、入力と出力があります。何が入力か、どんな出力を得るかを、”明確に”把握してください。入力からどんな出力を得るかが把握できれば、その間にある”何か”が、”どうあるべきか”が、自ずと見えるでしょう。
処理はメソッドにまとめる(C言語では関数)
意味のある塊で、複数箇所で同じ処理をするものは、メソッドにまとめます。1つの処理の塊を、1つの塊として、名前をつけることは、とても重要なことです。
メソッドは、引数と処理と返値があります。
メソッドの利点は:
- もしも同じ機能のコードをベタ書きしていたら
- なにかを修正するとき、全てのベタ書き部分を、漏れなく修正しなければいけない。(これは、うっかりミスが入ります。不思議と、なぜか、必ず、ミスします。)
- 読みやすい
- 処理でメソッドを呼び出すので、処理に名前がついていて、テキストも1行に収まるので、読みやすい。
プログラムを作るときは
プログラムを書く前に、発想から実装に至る流れを、”日本語で”書いてください。それは、目標はなにか、その目標を達成する手段はなにか(手段がわからない場合は、どんな手段が使えそうかを予想する)を押さえてください。
日本語で表現できないものを、プログラミング言語で作れることは、ありません。かならず、日本語で明確に、書いてください。文章にするのが面倒な場合は、適切な図をつかって、口頭で日本語で説明ができるようにしてください。この時に、主語、目的語、動詞を省略しない、日本語で書くことを意識してください。
例えば:
- 今回の発想、目的は、UFOを動かすことです。
- OK、動かすことです。どう動かす?
- それは、ランダムに動かすことです。
- OK。それは瞬間移動するの?
- 移動はなめらかにアニメーションで、徐々に加速して、停止地点の手前から減速して止まります。
- OK。その移動速度はどれくらい?
- ある1点からある1点まで、アニメーションで移動するのにかかる時間は0.5秒です。0.5秒後に次の移動が始まります。
- OK。それなら、プログラミングできるよ。
NSTimer絡みの例外発生
Xcodeが今使っているコンパイラllvmは、コーディング中に、ソースコードをみて論理的に間違いあるいは間違いではないかと疑わしい箇所を指摘してくれます。
今回は、一定時間ごとにアニメーションを開始するために、NSTimerを使いました。NSTimerは、呼び出すインスタンスtargetとメソッドを指定します。そのメソッド指定を間違えると(引数をとるのに最後の":"を忘れていると)、インスタンスが呼び出すべきメソッドを実装していないと、例外が発生します。
このようなエラーは、ソースコードを見てもllvmには論理的に検出できないものです。実装時は、よく注意します。
今回はmain.mのmain関数で@try ~ @catchでNSExceptionを取り、スタック情報をNSLogで表示して、NSTimerが原因だと追いました。
このエラーは、アプリケーションを落とします。NSTimerはUIと同じNSRunLoopで実行されるため、NSTimerを生成した自分のコードから、随分違う場所で例外が発生します。このような、原因とエラー発生箇所(もしくは発生時間)がずれるタイプの不具合は、十分な知識がないと対処は難しいです。経験がないなら、他人のヘルプを求めましょう。
デバッグ
思ったとおりに動かないことを、バグがある、といいます。これを動くように修正することを、バグを消す意味で、デバッグといいます。
デバッグに入る前に、腹をくくってください
何度も繰り返しますが、デバッグは”作業”ですが、仕事かどうかは、怪しい場合があります。
肉体も精神も疲労する作業なので、仕事と誤解することがありますが、実作業者視点から成果物を生み出すマネージャ視点から、いちど全体を見渡してみてください。それは、成果物に、役立っていますか?
そして、1つのバグがあれば、100のバグがあると思え、とも言います。”動いているからいい”で1つのバグを解消したら、その作業が、新たなバグを生み出しているかもしれません。また、そのバグの周辺に99のバグが潜んだままかもしれません。
コードをよく読めば解消できるものかもしれません。
デバッグ作業でツールを使いステップ実行を繰り返し、徹夜の果てに、1つのバグを潰しただけならば、それはのこり99個のバグでも同じ分量の作業が必要です。
理想論ですが、開発の労力を増やさずに、デバッグ作業がゼロに等しくできる開発があれば、それは、しかし全て遠き理想郷ですね。
デバッグでみるもの
- そこを実行しているか
- その実行での数値や処理が正しいか