タイトルの通り、自分がiOSアプリ開発に使っているデバッグ術を載せました。他にも山ほどあると思いますが、iOS始めたてでコードの読み方が分かんないって人におすすめです。
1.出力関数
1-1.出力関数とは?
引数に与えられた項目をConsoleに出力するメソッドです。
printメソッドが代表的ですが、実は3種類あります。
let range = 1...5
// 最もシンプルな出力関数。引数の値を出力する。
print(range) // 1...5
// printよりちょっとdebugに使える情報を追加して出力してくれるメソッド。
debugPrint(1...5) // CountableClosedRange(range)
// より詳細に情報を出力するメソッド。インスタンスの構造を出力してくれる。
dump(1...5) // CountableClosedRange(range)
// - lowerBound: 1
// - upperBound: 5
1-2.出力関数の使いどころ
変数を出力して、中身を確認したい時に使います。中身の確認はブレークポイントを貼ればlldbコマンドのpoから調べることもできますが、処理を止めずに中身を確認したい時や複数の変数を一度のビルドで同時に出力してConsoleに並べたい時などはprintを使ったほうが有効です。
2.検索機能
2-1.検索機能とは?
Xcodeにはコードを追跡する機能がいくつか用意されています。
⌘を押しながらコードにカーソルを合わせてクリックすると、コード検索機能を提供するポップオーバーが出てきます。
2-1-1.Jump to Definition
その1番目にあるのがJump to Definitionです。
名前の通りそのインスタンスの定義されている箇所にジャンプできます。
これってどんな変数だっけ? これってどんな処理をする関数だっけ? って確認する時に使います。
「Ctrl + ⌘ クリック」でポップオーバーを出さずにショートカットできます。
2-1-2.Show Quick Help
2番目がShow Quick Helpです。
その名の通りそのコードのヘルプを表示してくれます。
Show Quick Helpのいいところはコードのコメントをすぐに確認できるところです。
関数の役割を確認する時に毎度Jump to Definitionを使ってもいいですが、その度に画面を行き来するのは面倒です。
もしコメントで確認できるレベルの情報を得たい場合はShow Quick Helpでサクッと確認する方が効率が良いです。
「alt + クリック」でも表示できます。こっちの方が早いのでおすすめです。
2-1-3.Caller
3番目がCallerです。
その名の通り、そのコードが呼ばれるところを表示してくれます。
関数がどこの処理で呼ばれていてどう使われているか確認したい時に使います。
2-1-4.Find Call Hierarchy
Callerの強化版です。
コードの呼び出し元を階層で表示してくれます。
指定したコードがどこで呼ばれてるか → その箇所のコードがどこで呼ばれているか → その箇所のry
といった感じでコードの呼び出し元を順々に追跡したい時に使います。
こちらは上記3つとは違い、コードを右クリックした時に表示されるポップオーバーから使います。
2-2.検索機能の使いどころ
上記の機能はコードを読むときは必ず使います。
プログラマーはコードを書くよりも読む時間の方が長いらしいです。
仕様把握、コードレビュー、エラー監視などなどこれらの機能は必ず必要になるので初学者の方は是非使ってみてください。
2-3.ショートカット
Xcodeにはコードを検索するショートカットがいくつか用意されています。
僕がデバッグの時に使うのは以下の4つです。
コマンド | 説明 | 図 |
---|---|---|
⌘+shift+O | プロジェクト内からファイルやシンボル名を検索し、選んだものを即座に開く。 | |
⌘+shift+F | プロジェクト全体から検索文字を含むコードを検索する。 | |
⌘+F | ファイル内の検索文字列を含むコードを検索する。 | |
⌘+shift+J | 今表示してるファイルの階層を表示する。 |
2-4.ショートカットの使いどころ
キーワードから処理を検索したい時に使います。
例えば、「エラーのIDは分かるけどこれってどこのコードでエラー出してるんだっけ?」という時に「⌘+shift+F」で検索をかけると一発で該当の箇所が分かります。
2.ブレークポイント
2-1.ブレークポイントとは?
プログラムの実行を好きな地点で止めてくれる機能のことです。
2-2.ブレークポイントの使いどころ
- 特定の箇所まで処理を進めた時の変数の中身を確認したい時。
- 処理の実行順序を確認したい時。
2-3.ブレークポイントの使い方
処理を止めたい箇所の行番号をクリック→アプリの実行→処理が止まります。
ブレークポイントは行番号の青いリボンをタップすることで無効にできます。
(見え辛いけど薄い青になったら無効になってます。)
無効ではなく削除したい場合は、ドラッグして適当な所にドロップすると消えます。
または右クリック→「Delete BreakPoint」でも良いです。
2-3-1.変数の中身を確認する
処理を止めた状態で変数にカーソルを合わせると、処理が止まった時点でその変数に格納されている値を表示してくれます。
また、下のデバッグエリアにはスコープ内の他の変数とその中身を表示してくれます。
より詳細に確認したい時はデバッグエリアを参照しましょう。
2-3-2.処理の実行順序を確認する。
ブレークポイントで止めた箇所から処理を進めることで、実行順序を確認できます。
処理の進め方には4つ種類があり、以下のコンソール上部にあるボタンから選択できます。
それぞれ見ていきましょう。
Continue program execution
1番左側のボタンです。
ブレークした状態から処理を再開し、次のブレークポイント、もしくは最後まで進みます。
Step over
2番目のボタンが「Step over」です。
ブレークした箇所から1ステップ(=1行分)処理を進めます。
その時関数を実行していた場合は、その関数を実行した上で一行進みます。
関数の内部には入らず、それを飛ばして一行分の処理を進めるため「ステップオーバー」です。
飛ばす関数の中にブレークを貼っていた場合はそのブレークで止まります。
Step into
3番目のボタンが「step into」です。
こちらもStep over同様1ステップ処理を進めますが、関数があった場合はその関数の内部に入ってステップを実行します。
飛ばさずに内部に入って処理を進めるので「ステップイントゥ」です。
Step out
4番目のボタンが「Step out」です。
こちらは「Step intoで関数の内部に入ったけどやっぱ出たい」って時に使います。
2-3-3.スレッドを確認する
Breakで止まった状態では左側のNavigatorからDebugNavigatorを選択することで、アプリがどのスレッドで何をしているか確認することができます。
(めっちゃ雑な画像ですみません。)
この機能のいいところは、処理を止めた時点でアプリのどのViewControllerのどのライフサイクルメソッドが呼ばれているか確認できることです。
例えば上の画像ではFourthというクラスにBreakを貼っていますが、DebugNavigatorからはViewControllerのviewDidLoad()が実行されていることが分かります。
他にもViewの処理がメインスレッドで行われているかを確認することにも使えます。
3.lldbコマンド
3-1.lldbコマンドとは?
XcodeというIDEにはlldbというデバッガが標準で搭載されています。コードをビルドした時にエディタの下部に表示されるデバッグコンソールでは、このlldbのコマンドを用いてコマンドからデバッグが可能です。
3-2.lldbコマンドの使いどころ
lldbコマンドは種類がたくさんあるため、コマンドによって使い所は異なります。
今回は最もよく使うhelpコマンドとpoコマンドだけ紹介します。
helpコマンドはデバッグコンソールから使用できるlldbコマンドの説明を見たい時に使います。
poコマンドは変数や関数の値を出力したい時に使います。
関数も評価して値を出力できるところがポイントです。
変数であればブレークポイントで止めた状態でカーソルを合わせることで中身を確認できますが、関数単位で返り値を確認したい際や引数の値を変更して式を評価したい場合はデバッグコンソールが便利です。
3-3.lldbコマンドの使い方
helpコマンド
helpと打てばabc順で使えるコマンドを出力してくれます。
基本poくらいしか使いませんが、
(lldb) help
Debugger commands:
apropos -- List debugger commands related to a word or subject.
breakpoint -- Commands for operating on breakpoints (see 'help b' for
shorthand.)
bugreport -- Commands for creating domain-specific bug reports.
command -- Commands for managing custom LLDB commands.
disassemble -- Disassemble specified instructions in the current
target. Defaults to the current function for the
current thread and stack frame.
help + コマンド名でコマンドの詳細を出力することもできます。
help <コマンド名(poとか)>
poコマンド
変数、または関数を評価して出力します。
po <変数 or 関数>