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__))