I have a project with a lot of classes.
I want to log (e.g. to stderr) invocations of each selector in runtime.
My main requirement is not to change the existing code, so I can't just log the function's params at the start of each call.
If some method is invoked during program execution, e.g.
@implementation Class1
// ...
- (int)someFunc:(Class2*) a andClass3:(Class3*)b
{
}
// ...
@end
I want to replace it with something like:
- (int)someFuncWrapper:(Class2*) a andClass3:(Class3*)b
{
NSLog(@"- (int)someFuncWrapper:a andClass3:b <= a=%@, ab=%@", a, b);
return [someFunc: a andClass3:b];
}
Is it possible?
I've read of method swizzling, KVO, forward messaging.
My current approach with method swizzling causes infinite recursion:
- (int)funcToSwizzle:(int)a andB:(int)b
{
int r = a+b;
NSLog(@"funcToSwizzle: %d", r);
return r;
}
- (void)doSimpleSwizzling
{
NSLog(@"r1 = %d", [self funcToSwizzle:10 andB:20]);
Class curClass = NSClassFromString(@"HPTracer");
unsigned int methodCount = 0;
Method *methods = class_copyMethodList( curClass, &methodCount);
for (int i=0; i<methodCount; ++i)
{
SEL originalSelector = method_getName(methods[i]);
if ( strcmp("funcToSwizzle:andB:", sel_getName(originalSelector)) == 0 )
{
Method m1 = class_getInstanceMethod(curClass, originalSelector);
id block3 = ^(id self, int a, int b) {
NSLog(@"My block: %d", a*b);
// get current implementation of "funcToSwizzle".
// copy it. store that "IMP"/"void *" etc
return [self funcToSwizzle:a andB:b];
};
IMP imp3 = imp_implementationWithBlock(block3);
method_setImplementation(m1, imp3);
}
}
NSLog(@"r2 = %d", [self funcToSwizzle:10 andB:20]);
}
And I'm afraid it's impossible to generate a block3
or some method in runtime. There's NSSelectorFromString
but no ImplementationFromString
.
UPD
I looked at DTrace util, it seems very powerful, but doesn't fit my needs.
It requires disabling SIP on Mac OS, and is either impossible on iOS or possible on jailbreaked device.
What I need from methods interceptions is creating a stable custom "framework" for both Debug and production build modes.