특정 동작 및 메소드 실행시간 측정을 하는 코드입니다.
아래와 같은 목적으로 코드가 작성되었습니다.
- 기존의 코드 및 구조에 영향을 주지 않을 것.
- 무조건 간단할 것. 작성도 사용도.
동작은 간단합니다.
- 동작이 시작되는 곳에서 태그 (Log) 를 남김.
- 동작이 끝나는 곳에서 태그 (Log) 를 남김.
objc_setAssociatedObject
objc/runtime.h 에 포함된 함수로 런타임 객체에 속성(property) 혹은 메소드를 추가할 수 있습니다. (바로가기)
시간측정에 사용될 Date 속성을 기존 객체 코드 수정없이 런타임으로 추가하기 위해 사용합니다.
동작(메소드) 시작 시점의 Date 속성을 추가하고 끝나는 시점 Date 속성을 제거합니다.
구현
// 측정 시작
- (void)tickWithName:(NSString *)name LineTag:(NSString *)tag {
NSDate *startDate = objc_getAssociatedObject(self, CFBridgingRetain(name));
if (!startDate) {
startDate = [NSDate date];
NSLog(@"Tick (%@, %@): %f", name, tag, [startDate timeIntervalSinceNow]);
objc_setAssociatedObject(self, CFBridgingRetain(name), startDate, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
}
// 측정 종료
- (void)tockWithName:(NSString *)name LineTag:(NSString *)tag {
NSDate *startDate = objc_getAssociatedObject(self, CFBridgingRetain(name));
if (startDate != nil) {
NSLog(@"Tock (%@, %@): %f", name, tag, [startDate timeIntervalSinceNow]);
objc_setAssociatedObject(self, CFBridgingRetain(name), nil, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
startDate = nil;
}
}
이 함수를 Preprocessor Define MACRO 를 통해 간편하게 만듭니다.
#ifdef RELEASE_VER
#define TICK(a)
#define TOCK(b)
#else
#define TICK(a) [self tickWithName:a LineTag:[NSString stringWithUTF8String:__PRETTY_FUNCTION__]]
#define TOCK(b) [self tockWithName:b LineTag:[NSString stringWithUTF8String:__PRETTY_FUNCTION__]]
#endif
어디서나 사용 가능하도록 NSObject 의 카테고리(Category)로 추가합니다.
이제 아래와 같이 사용합니다.
- (void)viewDidLoad {
TICK(@"MainViewController viewDidLoad");
……….
TOCK(@"MainViewController viewDidLoad");
}
전체소스 바로가기입니다.