Edited at

[Deprecated] CocoaLumberjack の ddLogLevel のラッパーマクロを定義した

More than 1 year has passed since last update.

追記:これは CocoaLumberjack バージョン 1.x(Objective-C 版)向けの記事です。既にバージョン 2.x および Swift が主流となっているため、この記事の内容は Deprecated(非推奨)としておきます。


CocoaLumberjack とは


CocoaLumberjack is a fast & simple, yet powerful & flexible logging framework for Mac and iOS.


CocoaLumberjack は Cocoa 用のロギングフレームワークです。基本的な使い方については iPhone - ログ出力ライブラリのCocoaLumberjackを使う - Qiita あたりを参照してください。

私は XcodeColors で色分けもしています。

Xcodeのコンソール出力に色をつけて見やすくしよう〜XcodeColorsとCocoaLumberjack〜 | Developers.IO


定義したマクロ

***-Prefix.pch もしくはそれが #import しているヘッダー(つまり全ファイルから見えるヘッダー)に以下のマクロを定義します(XXX はベンダープレフィックス)。


XXXCommon.h

#ifdef DEBUG

#define XXXGlobalLogLevel LOG_LEVEL_VERBOSE
#else
#define XXXGlobalLogLevel LOG_LEVEL_INFO
#endif

#define XXXLogLevel(level) __attribute__((unused)) static const int LOG_LEVEL_DEF = (XXXGlobalLogLevel) < (level) ? (XXXGlobalLogLevel) : (level)

各 *.m ファイルの頭の方(#import 直後あたり)でログレベルの制御を以下のように書けます。


XXXObject.m

XXXLogLevel(LOG_LEVEL_DEBUG);



コア部分抜粋


抜粋

__attribute__((unused)) static const int LOG_LEVEL_DEF =

(XXXGlobalLogLevel) < (level) ? (XXXGlobalLogLevel) : (level);

LOG_LEVEL_DEF の実態はデフォルトでは ddLogLevel です。


得られる効果



  • 字数削減


    • Before: static const int ddLogLevel = ...;

    • After: XXXLogLevel(...);




  • __attribute__((unused)) の力により Unused variable warning を抑止


  • XXXGlobalLogLevel により グローバルにログのレベルを制御可能



    • XXXGlobalLogLevel 以下のレベルのログは表示しない

    • 例えば XXXGlobalLogLevelLOG_LEVEL_OFF にすれば全ログを一気に非表示にできる

    • *.m 側でより厳しい(quiet な)レベルが指定されていたらそっちを採用

    • ここでは DEBUG 定義の有無で XXXGlobalLogLevel の内容を変えている




おまけ:NSObjCRuntime.h の MIN マクロ

最初 MIN マクロを使ってたんだけど Statement expression not allowed at file scope というエラーが出た。MIN マクロの定義を見るとこんなんなってた。


NSObjCRuntime.h

#define __NSX_PASTE__(A,B) A##B


#if !defined(MIN)
#define __NSMIN_IMPL__(A,B,L) ({ __typeof__(A) __NSX_PASTE__(__a,L) = (A); __typeof__(B) __NSX_PASTE__(__b,L) = (B); (__NSX_PASTE__(__a,L) < __NSX_PASTE__(__b,L)) ? __NSX_PASTE__(__a,L) : __NSX_PASTE__(__b,L); })
#define MIN(A,B) __NSMIN_IMPL__(A,B,__COUNTER__)
#endif

一度変数に代入することでマクロ引数に含まれる関数が多重実行されないようにしているっぽい。それが原因でファイルスコープで MIN, MAX が使えないようだ。