I am messing around with method swizzling and would like to call the original function after performing a method_exchangeImplementations
. I have two projects I have setup for this.
The first project is the main project for the application. This project includes all of the logic for the application. Notice that originalMethodName
is called when the view loads.
@implementation ViewController
- (void)originalMethodName
{
NSLog(@"REAL %s", __func__);
}
- (void)viewDidLoad {
[super viewDidLoad];
NSLog(@"REAL %s", __func__);
[self originalMethodName];
}
@end
The second project includes only the code for swizzling. I have a method swizzle_originalMethodName
which includes the code I want to inject into the main application with the originalMethodName
function is called.
@implementation swizzle_ViewController
- (void)swizzle_originalMethodName
{
NSLog(@"FAKE %s", __func__);
}
__attribute__((constructor)) static void initializer(void)
{
NSLog(@"FAKE %s", __func__);
Class c1 = objc_getClass("ViewController");
Class c2 = [swizzle_ViewController class];
Method m1 = class_getInstanceMethod(c1, @selector(originalMethodName));
Method m2 = class_getInstanceMethod(c2, @selector(swizzle_originalMethodName));
method_exchangeImplementations(m1, m2);
}
@end
The swizzle is working just fine (as seen in the output below), but now I want to be able to call originalMethodName
from the swizzle_originalMethodName
2016-08-17 14:18:51.765 testMacOS[7295:1297055] FAKE initializer
2016-08-17 14:18:51.822 testMacOS[7295:1297055] REAL -[ViewController viewDidLoad]
2016-08-17 14:18:51.822 testMacOS[7295:1297055] FAKE -[swizzle_ViewController swizzle_originalMethodName]
I have tried to use NSInvocation
but am not having any luck. Any ideas what I am doing wrong?
Class c1 = objc_getClass("ViewController");
Method m1 = class_getInstanceMethod(c1, @selector(originalMethodName));
NSMethodSignature *methodSignature = [NSMethodSignature signatureWithObjCTypes:method_getTypeEncoding( m1)];
NSInvocation *originalInvocation = [NSInvocation invocationWithMethodSignature:methodSignature];
[originalInvocation invoke];