Print any method in an Objective-C object with ANYMethodLog
+ (void)logMethodWithClass:(Class)aClass
condition:(BOOL(^)(SEL sel)) condition
before:(void(^)(id target, SEL sel, NSArray *args, int deep)) before
after:(void(^)(id target, SEL sel, NSArray *args, NSTimeInterval interval, int deep, id retValue)) after;
aClass:The class to be logged
condition:Whether or not to track the method according to this block (sel is the method name)
before:block will be called before the method (target is the detected object, sel is the method name, args is the parameter list, and deep is the calling level)
after:block will be called after the method (interval is time spent executing the method, and retValue is the return value)
- Print all methods defined by a class, including public and private methods:
[ANYMethodLog logMethodWithClass:[UIViewController class] condition:^BOOL(SEL sel) {
NSLog(@"method:%@", NSStringFromSelector(sel));
return NO;
} before:nil after:nil];
- Print which methods are called during the run:
[ANYMethodLog logMethodWithClass:[UIViewController class] condition:^BOOL(SEL sel) {
return YES;
} before:^(id target, SEL sel, NSArray *args, int deep) {
NSLog(@"target:%@ sel:%@", target, NSStringFromSelector(sel));
} after:nil];
- Print the calling sequence of specific methods:
[ANYMethodLog logMethodWithClass:[UIViewController class] condition:^BOOL(SEL sel) {
NSArray *whiteList = @[@"loadView", @"viewWillAppear:", @"viewDidAppear:", @"viewWillDisappear:", @"viewDidDisappear:", @"viewWillLayoutSubviews", @"viewDidLayoutSubviews"];
return [whiteList containsObject:NSStringFromSelector(sel)];
} before:^(id target, SEL sel, NSArray *args, int deep) {
NSLog(@"target:%@ sel:%@", target, NSStringFromSelector(sel));
} after:nil];
- Print the parameter values when calling the method:
[ANYMethodLog logMethodWithClass:NSClassFromString(@"UIViewController") condition:^BOOL(SEL sel) {
return [NSStringFromSelector(sel) isEqualToString:@"viewWillAppear:"];
} before:^(id target, SEL sel, NSArray *args, int deep) {
NSLog(@"before target:%@ sel:%@ args:%@", target, NSStringFromSelector(sel), args);
} after:nil];
- Print the changes before and after a method call:
[ANYMethodLog logMethodWithClass:NSClassFromString(@"ListController") condition:^BOOL(SEL sel) {
return [NSStringFromSelector(sel) isEqualToString:@"changeBackground"];
} before:^(id target, SEL sel, NSArray *args, int deep) {
NSLog(@"before background color:%@", [(ListController *)target view].backgroundColor);
} after:^(id target, SEL sel, NSArray *args, NSTimeInterval interval, int deep, id retValue) {
NSLog(@"after background color:%@", [(ListController *)target view].backgroundColor);
}];
- Print the time elapsed for a method call::
[ANYMethodLog logMethodWithClass:NSClassFromString(@"ListController") condition:^BOOL(SEL sel) {
return [NSStringFromSelector(sel) isEqualToString:@"changeBackground"];
} before:^(id target, SEL sel, NSArray *args, int deep) {
} after:^(id target, SEL sel, NSArray *args, NSTimeInterval interval, int deep, id retValue) {
NSLog(@"interval::%@", [@(interval) stringValue]);
}];
- Trace the method call sequence::
[ANYMethodLog logMethodWithClass:NSClassFromString(@"ListController") condition:^BOOL(SEL sel) {
return YES;
} before:^(id target, SEL sel, NSArray *args, int deep) {
NSString *selector = NSStringFromSelector(sel);
NSArray *selectorArrary = [selector componentsSeparatedByString:@":"];
selectorArrary = [selectorArrary filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"length > 0"]];
NSMutableString *selectorString = [NSMutableString new];
for (int i = 0; i < selectorArrary.count; i++) {
[selectorString appendFormat:@"%@:%@ ", selectorArrary[i], args[i]];
}
NSMutableString *deepString = [NSMutableString new];
for (int i = 0; i < deep; i++) {
[deepString appendString:@"-"];
}
NSLog(@"%@[%@ %@]", deepString , target, selectorString);
} after:^(id target, SEL sel, NSArray *args, NSTimeInterval interval, int deep, id retValue) {
NSMutableString *deepString = [NSMutableString new];
for (int i = 0; i < deep; i++) {
[deepString appendString:@"-"];
}
NSLog(@"%@ret:%@", deepString, retValue);
}];
- Solving the problem of running on real machines. (completed)
- Printing the parameter value at the time of the call. (completed)
- Printing the return value. (completed)
- Calculating the time taken for a method. (completed)
-
Replace the
IMP
of the original method with_objc_msgForward
to trigger theforwardInvocation
method; -
Replace the
IMP
of the methodforwardInvocation
withqhd_forwardInvocation
-
Create a new method,
IMP
overwrites the original method, then just call the new method inqhd_forwardInvocation
. Then you can insert log inqhd_forwardInvocation
.
Issues and Pull requests are welcome