デバッグを効率化するアイディア
デバッグを簡単にする一つのアイディア。
実行したメソッドの、クラス名、メソッド名、引数をすべてGDBに出力します。
これでエラーが起きた時にメソッドの逆追いが凄く楽になります。
void DEBUG_PRINT( id my , SEL sel , char *argv , ... ) { printf("%s",[[NSString stringWithFormat:@"[Class:]%@ [Method:]%s",[my class],sel ] UTF8String]); //引数 ... の部分を展開 va_start( list , argv ); for( cp=( char * )argv ; *cp != '\0' ; cp++ ) { //\0→バックスラッシュに変換してね switch ( *cp ){ case 's': printf( "%s" , va_arg( list , char * ) ); break; //Cのchar*(文字列) case 'f': printf( "%f" , va_arg( list , float ) ); break; //Cのfloat、CGFloatなど case 'c': printf( "%c" , va_arg( list , char ) ); break; //Cのcharなど case 'i': printf( "%d" , va_arg( list , int ) ); break; //Cのint、CGIntなど case 'S': printf( "%s" ,[va_arg( list , void* ) UTF8String]); break; //NSString* case 'C': printf( "%s" ,[[va_arg( list , void* ) class] UTF8String]; break; //インスタンス //引数に使いたいデータ型を追加してね } printf(","); //データの区切り } va_end( list ); printf ("\n"); //¥→バックスラッシュに変換してね }
このC関数をどこかに記述して、使いたい〜.mで#include(#import)してください。
通常、各メソッドで引数のデータ型も個数もバラバラだろうと思いますので、違いを吸収するためにC特有の可変長引数を使用しています(引数の...の部分)
使い方は各メソッドの一番最初に
-(void)Sample:(int)num :(NSString*)nsstr :(MyClass*)mycls{ DEBUG_PRINT( self , _cmd , "iSC" , num , nsstr , mycls ); //以下メソッドのプログラム〜 }
DEBUG_PRINTを挿入し、1つ目の引数はself、2つ目は_cmd
3つ目は、各引数のデータ型を指定してやります。上記の例ならば
"iSC" → 1つ目の引数i(int型) 2つ目の引数S(NSString*型) 3つ目の引数C(クラス)
各文字の意味はDEBUG_PRINT関数を見てください。
適宜プログラムに合わせて必要なデータ型を追加してください。
上記の出力イメージは
[Class:]SampleClass [Method:]Sample:int:NSString*:MyClass:10,引数文字列,MyClass
呼び出されたクラス、メソッド、引数の型、引数の内容がそれぞれ出力されます
ちなみにDEBUG_PRINTはC関数ではなくObjective-Cのメソッドに出来るのですが、たまたま今使っているのがCだったので、そのまま出しちゃいます。
バグがあったら教えて下さい