Edited at

ログ出力をもっと便利に簡単にするマクロ

More than 5 years have passed since last update.

Qiitaに投稿されたNSDictionaryOfVariableBindingsマクロを見て思いついたログ出力用マクロ


使い方


AppDelegate.m

id var1 = @"hoge";

VARLOG(var1);

id var2 = @{@"huga": @"hoge"};
VARLOG(var1, var2);

// output
// -[AppDelegate application:didFinishLaunchingWithOptions:] at LINE:78
// {
// var1 = hoge;
// }
//
// -[FKAppDelegate application:didFinishLaunchingWithOptions:] at LINE:81
// {
// var1 = hoge;
// var2 = {
// huga = hoge;
// };
// }



メリット


  • 変数名を渡すだけで他の箇所、他の変数との区別がある程度可能なログ出力が出来る


デメリット


  • 表示に利用できる型はNSObject Protocolを継承している型のみ

  • カンマで渡された変数の個数をカウントしているので、途中に意図しないカンマが入る変数名は利用できない

VARLOG(@[@"hoge", @"huga"]); -> NG

VARLOG([NSString stringWithFormat:@"%@", @"hoge"]); -> NG


実装

NSDictionaryOfVariableBindingsを利用していたが、


  • 対象の変数がnilの場合クラッシュする

  • 空白でも区切られてしまう

  • NSDictionaryになるため日本語を出力しようとするとユニコード表記になる

のため最終的には利用せず


ver.1.0.0

#define VAR(...) _VAR(@""#__VA_ARGS__, __VA_ARGS__)

//#define VAR(var, ...) NSDictionaryOfVariableBindings(var, ##__VA_ARGS__)

#define _VAR(...) \
^NSString *(NSString *format, ...) {\
va_list args;\
format = [format stringByReplacingOccurrencesOfString:@", " withString:@","];\
format = [format stringByReplacingOccurrencesOfString:@" ," withString:@","];\
NSArray *keys = [format componentsSeparatedByString:@","];\
\
NSMutableArray *objects = [NSMutableArray arrayWithCapacity:keys.count];\
\
va_start(args, format);\
for (int i = 0; i < keys.count; i++) {\
id object = va_arg(args, id);\
object = object ? object : @"nil";\
[objects addObject:object];\
}\
va_end(args);\
\
NSMutableString *buffer = [NSMutableString stringWithString:@"{\n"];\
\
[objects enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {\
id key = [keys objectAtIndex:idx];\
id description = obj;\
if ([obj respondsToSelector:@selector(descriptionWithLocale:indent:)]) {\
description = [obj descriptionWithLocale:nil indent:1];\
}\
[buffer appendFormat:@"\t%@ = %@;\n", key, description];\
}];\
\
[buffer appendString:@"}"];\
return buffer;\
}(__VA_ARGS__)

#define VARLOG(var, ...) NSLog(@"\n%s at LINE:%d\n%@\n\n", __func__, __LINE__, VAR(var, ##__VA_ARGS__))