Я использую метод swizzling и хотел бы вызвать исходную функцию после выполнения method_exchangeImplementations
. У меня есть два проекта, для которых я настроен.Вызов функции из функции swizzled
Первый проект является основным проектом для приложения. Этот проект включает в себя всю логику для приложения. Обратите внимание, что при отображении представления вызывается originalMethodName
.
@implementation ViewController
- (void)originalMethodName
{
NSLog(@"REAL %s", __func__);
}
- (void)viewDidLoad {
[super viewDidLoad];
NSLog(@"REAL %s", __func__);
[self originalMethodName];
}
@end
Второй проект включает только код для swizzling. У меня есть метод swizzle_originalMethodName
, который включает в себя код, который я хочу ввести в основное приложение с помощью функции originalMethodName
.
@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
надираться работает нормально (как показано в приведенном ниже примере), но теперь я хочу, чтобы иметь возможность вызывать originalMethodName
из 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]
Я пытался использовать NSInvocation
, но я не повезло. Любые идеи, что я делаю неправильно?
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];
Как насчет просто вызова '[self swizzle_originalMethodName];'? Этот селектор должен вернуться к первоначальной реализации после обмена. –
Это гений. Не знаю, почему это не произошло со мной. Я все еще получаю сообщение об ошибке, и я не уверен, как его решить. '- [ViewController swizzle_originalMethodName]: непризнанный селектор отправлен в экземпляр 0x7ff72974a670' –
А, правильно ... вы перебираете разные классы. Мне нужно подумать об этом. –