iOS/iPhone/iPad/watchOS/tvOS/MacOSX/Android プログラミング, Objective-C, Cocoa, Swiftなど
先日のmosa entrance #21で思いついた事だ。
以前、C++を使っていた頃。そう、AT&Tからcfrontという名前でC言語のプリプロセッサとしてリリースされていた事の話。C++はnewしなくても変数宣言して使えて、この自動変数の寿命にタイミング、構築子/破滅子でデバッグ出力させる事によって、関数トレースをさせていた。
Objective-CのARCは、alloc/initされたクラスのインスタンスが、自動変数のような振る舞いをするので、もしかしたら、同じ事が出来るのではと思って、試してみた。
@interface DebugMessage : NSObject
- (id)initWithString:(NSString *)aString;
@end
@interface DebugMessage ()
@property (strong, nonatomic) NSString *dbgMsg;
@end
@implementation DebugMessage
@synthesize dbgMsg = _dbgMsg;
- (id)init
{
return [self initWithString:@""];
}
- (id)initWithString:(NSString *)aString
{
self = [super init];
if (self) {
self.dbgMsg = [[NSString alloc] initWithString:aString];
if (self.dbgMsg) {
NSLog(@"[BEGIN]%@", self.dbgMsg);
}
}
return self;
}
- (void)dealloc
{
if (self.dbgMsg) {
NSLog(@"[END]%@", self.dbgMsg);
}
self.dbgMsg = nil;
/* [super dealloc]; */
}
@end
#ifdef DEBUG
#define DBGMSG(...) NSLog(__VA_ARGS__)
#define TRC(aString) DebugMessage *dbgmsg = [[DebugMessage alloc] initWithString:aString]
#else /* DEBUG */
#define DBGMSG(...)
#define TRC(aString)
#endif /* DEBUG */
このTRC()マクロを以下のように宣言すれば!
- (void)viewDidLoad
{
TRC(@"ViewController # - viewDidLoad");
[super viewDidLoad];
}
-viewDidLoadメソッドの呼び出し前後で、トレースのメッセージが出力されている!
2012-07-12 19:29:46.204 DebugMessage[22897:f803] [BEGIN]ViewController # - viewDidLoad
2012-07-12 19:29:46.204 DebugMessage[22897:f803] [END]ViewController # - viewDidLoad
ただ、実際にサンプル・コードをビルドして実行すると分かるのだが、ARCが使えるビルド環境だと、マクロで宣言した変数dbgmsgが使われていないとか、だったら、メソッド呼び出しで変数は宣言しないようにしたら、今度は戻り値を受け取っていないとか、ビルド時に警告メッセージが出力されてしまう。
これは、大失敗のようだ。