実行時間を計測したいメソッドを最初に1回登録するだけでいい。
+(void) initialize { AddProfiler([MyClass class], @selector(foo)); } -(void) foo { ... }
Running [self foo] will print: *** Timer MyClass_foo started. *** *** Timer MyClass_foo stopped. runtime: 1.633041 milliseconds ***
1行と短い上に記述箇所は1箇所だし、デバッグコードをメソッド内に書く必要が無いのがいい。これは良いアイディア。
内部では TheWrapper という別のライブラリを使用している。
このライブラリではメソッドの呼び出し前と後でblocksを実行できるAPIを用意している。
+(void) addWrapperto:(id) target andSelector:(SEL) selector withPreRunBlock:(void (^)(va_list args)) preRunblock; +(void) addWrapperto:(id ) target andSelector:(SEL) selector withPostRunBlock:(id (^)(id functionReturnValue, va_list args)) postRunBlock; +(void) addWrapperto:(id ) target andSelector:(SEL) selector withPreRunBlock:(void (^)(va_list args)) preRunblock andPostRunBlock:(id (^)(id functionReturnValue, va_list args)) postRunBlock; +(void) addWrappertoClass:(Class) clazz andSelector:(SEL) selector withPreRunBlock:(void (^)(va_list args)) preRunblock; +(void) addWrappertoClass:(Class) clazz andSelector:(SEL) selector withPostRunBlock:(id (^)(id functionReturnValue, va_list args)) postRunBlock; +(void) addWrappertoClass:(Class) clazz andSelector:(SEL) selector withPreRunBlock:(void (^)(va_list args)) preRunblock andPostRunBlock:(id (^)(id functionReturnValue, va_list args)) postRunBlock; +(void) removeWrapperFrom:(id ) target andSelector:(SEL) selector; +(void) removeWrapperFromClass:(Class) clazz andSelector:(SEL) selector;
このライブラリでは Objective-CのランタイムAPIを使い、指定されたメソッドの実装を前後処理を加えた関数(WrapperFunction)で置き換えている。
メソッド → オリジナル実装 ↓ 置換 ↓ メソッド → WrapperFunction
WrapperFunction (){ preRunBlock実行; オリジナル実装実行; postRunBlock実行; }
面白い。このライブラリはデバッグで色々活用できそう。