2010-12-31
■ [NSLog] 今さら聞けないNSLogの話
![[NSLog] 今さら聞けないNSLogの話 - Ni chicha, ni limona - 平均から抜けられない僕 のブックマークコメント [NSLog] 今さら聞けないNSLogの話 - Ni chicha, ni limona - 平均から抜けられない僕 のブックマークコメント](http://r.hatena.ne.jp/images/popup.gif)
今更で本当に恥ずかしいことですが、自戒も込めて記事にしておきます。
NSLogで出力される中で[aaa:bbb]とある部分、これは[プロセスID:スレッドID]を表しています。プロセスIDである点は、NSLogvのマニュアル部分に載っているのですが、では右の値はどこから得ているのでしょう?
実際にGDBで確認してみましょう。実行中のスレッド情報をinfoコマンドで出力してみます。
(gdb) s 2010-12-31 08:01:14.096 MetronomePro[1183:207] hoge (gdb) info thread Thread 1 has current state "WAITING" Mach port #0x207 (gdb port #0x1403) ← ここ! -[KSPopoverViewController loadView] (self=0x8e558b0, _cmd=0x7414aa) at /Users/〜/KSPopoverViewController.m:48 frame 0: pthread ID: 0xa0b95540 system-wide unique thread id: 0x6ce4 dispatch queue name: "com.apple.main-thread" dispatch queue flags: 0x0 total user time: 120858000 total system time: 103652000 scaled cpu usage percentage: 0 scheduling policy in effect: 0x1 run state: 0x3 (WAITING) flags: 0x0 number of seconds that thread has slept: 0 current priority: 47 max priority: 63 suspend count: 0. (gdb)
gdbの出力から、右の番号がMah portのスレッドIDを表していることが分かりますね。ちなみにMach portについての説明は以下サイトで紹介されているPDFを読むと良いでしょう(とても良い内容です)。
いやあ、今まできちんと理解せずに使っていたので、何ともお恥ずかしい話です・・・。
■(応用編その1)凝ったNSLogにしたい
それだけだと恥さらしするだけで終わりですので、私が使っているNSLog代替のマクロを紹介しておきます。
#define KSLog(fmt, ...) \ NSLog((@"<%s/%d> " fmt), __PRETTY_FUNCTION__, __LINE__, ##__VA_ARGS__);
これはNSLogと同じように使え、さらに
- 現在の関数(見やすいフォーマット)
- 呼んだ行数
も同時に表示してくれる便利なマクロです。
■(応用編その2)NSLogを自前のログ出力関数とすげ替える方法
もう1つ、NSLogを自前の関数にすげ替えるテクニックを紹介します。まずはプリプロセッサを使う方法です。
// プリプロセッサで強制的に書き換えてしまう #define NSLog(...) MyLog(__VA_ARGS__) // 自前のログ出力 void MyLog(NSString *fmt, ...) { va_list ap; va_start (ap, fmt); #if 1 // NSLogvを使用する方法 NSLogv(fmt, ap); #else // fprintfで出力する方法 // NSLogと同様に、末尾の改行を入れ込む if (![fmt hasSuffix: @"\n"]) { fmt = [fmt stringByAppendingString: @"\n"]; } NSString *body = [[NSString alloc] initWithFormat:fmt arguments:ap]; fprintf(stderr, "MyLog:%s", [body UTF8String]); [body release]; #endif va_end(ap); } void MyUncaughtExceptionHandler(NSException *e) { MyLog(@"E:%@", [e reason]); } - (id)init { // 例外発生時に呼ばれる関数を設定 NSSetUncaughtExceptionHandler(&MyUncaughtExceptionHandler); : }
いやはや、defineマクロって恐ろしいですね。
そして、さらに荒々しい方法として、AppleのWebObjectsの記事で紹介されているこの方法によって、NSLogをSwizzlingしてしまう方法も紹介します。
// 準備 extern void _NSSetLogCStringFunction(void(*)(const char *, unsigned, BOOL)); static void _MyLogCString(const char *message, unsigned length, BOOL withSyslogBanner) { fprintf(stderr, "%s(%d[%s])\n", message, length, withSyslogBanner?"T":"F"); } - (id)init { // NSLogをすげ替え(プライベートAPI!) _NSSetLogCStringFunction(_MyLogCString); : }
これをランループを開始する前に呼んでしまえば、ことごとく差し替えられてしまうという、前述のプリプロセッサを使った方法よりも恐ろしい方法です。
ただ、この_NSSetLogCStringFunction()関数は、ほどのドキュメントにもあるとおりプライベートAPIですので、審査には確実に通りません(試してないですが)。
用法を守って、正しくお使いくださいませ。
催情丹(男女兼用)は、フランスを中心とする欧州各国で大人気の商品です。体中が熱くなり、全身が性感帯にはやがわり!催情丹(男女兼用)の使用効果には個人差があり、効果を保証するものではございませんので、あらかじめご了承ください。妊娠または授乳中の方、特別な治療を受けている方、または他の医薬品を服用中の方は、ご使用の... 催情丹(男女兼用)の使用効果には個人差があり、効果を保証するものではございませんので、あらかじめご了承ください。妊娠または授乳中の方、特別な治療を受けている方、または他の医薬品を服用中の方は、ご使用の前に、医師または薬剤師にご相談ください。何か違和感が生じましたら、服用を直ちに止め、かかりつけの医師などにご相談下さい。サプリメントはお客さまの自己責任にてお使いいただけますよう、よろしくお願いいたします。
勃起不能、早漏、性欲減退、やり過ぎ、男女性機能障害、倦怠感、腰や足が怠い痛い、冷え症、夜間尿頻などに効果があります。特に勃起不能、早漏にはよく効きます。
勃起と持続効果を発揮するドイツ生まれの男性用スプレーです。リドカインを主成分とし、仮性包茎や過敏による早漏を防止したい方へおすすめします。また、本来スポーツ選手など過激な運動によって体力を消耗する人が疲れた体を癒すための成分を、夜の生活用に特別配合です。強壮剤としても男性に広く愛される商品となりました。
超級猛男健力カプセル販売--精力剤:http://www.shanghaikanpo.com/view/1523.html
花痴:http://www.shanghaikanpo.com/view/1363.html
D5原液:http://www.hellokanpo.com/view/FLYD5yuan.html
蒼蝿水:http://www.hellokanpo.com/view/FLY-D5.html
中華牛鞭:http://www.kanpoucom.com/product/167.html
中華牛宝:http://www.kanpoucom.com/product/634.html
街頭覇王睾丸素カプセル:http://www.kanpoucom.com/product/694.html