如何实现方法swizzling? [英] How do I implement method swizzling?

查看:104
本文介绍了如何实现方法swizzling?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图修改程序的行为(我没有它的源)使用SIMBL。我使用类转储,发现我需要覆盖一个实例方法



这个方法是在类中的控制器。所有我需要做的是获取参数arg1和它。也许NSLog它或发布通知...
我阅读关于方法swizzling在objective-c,但如何使用它?我需要引用MessageController类,我当然没有。



谢谢!

解决方案

我猜你需要在执行NSLog之后调用原来的实现;如果没有,你可以只使用类上的类别来覆盖该方法。



要混合该方法,首先需要一个替换方法。我通常把类似这样的东西在目标类上的类别:

   - (void)replacementReceiveMessage:(const struct BInstantMessage *) arg1 {
NSLog(@arg1 is%@,arg1);
[self replacementReceiveMessage:arg1];
}

看起来它会递归调用自身, '方法调用 replacementReceiveMessage: ReceiveMessage: >调用旧版本。



第二步是使用运行时函数实际执行交换。使用类别的优点是,您可以在类别中使用加载来完成工作:

  +(void)load {
SEL originalSelector = @selector(ReceiveMessage :);
SEL overrideSelector = @selector(replacementReceiveMessage :);
方法originalMethod = class_getInstanceMethod(self,originalSelector);
方法overrideMethod = class_getInstanceMethod(self,overrideSelector);
if(class_addMethod(self,originalSelector,method_getImplementation(overrideMethod),method_getTypeEncoding(overrideMethod))){
class_replaceMethod(self,overrideSelector,method_getImplementation(originalMethod),method_getTypeEncoding
} else {
method_exchangeImplementations(originalMethod,overrideMethod);
}
}

有两种情况需要处理: / p>


  • 如果我们正在搅拌的方法实际上是在超类中定义的,我们必须使用 class_addMethod 向目标类添加 ReceiveMessage:的实现,我们使用替换实现。然后我们可以使用 class_replaceMethod 替换 replacementReceiveMessage:与超类的实现,所以我们的新版本将能够正确调用 c。如果在目标类中定义了方法, class_addMethod 将会失败,但是我们可以使用 method_exchangeImplementations 即可交换新旧版本。


I am trying to modify behaviour of a program (i dont have it's source) using SIMBL. I used class dump and found out that I need to overide an instance method

This method is in the class called controller. All I need to do is get the argument arg1 and thats it. Maybe NSLog it or post a notification... I read about method swizzling in objective-c but how can I use it?. I would need to refer to the class MessageController whose course i don't have.

Thanks!

解决方案

I'm guessing you need to call the original implementation after doing your NSLog; if not, you may be able to just use a category on the class to override the method.

To swizzle the method, first you need a replacement method. I usually put something like this in a category on the target class:

- (void)replacementReceiveMessage:(const struct BInstantMessage *)arg1 {
    NSLog(@"arg1 is %@", arg1);
    [self replacementReceiveMessage:arg1];
}

This looks like it will recursively call itself, but it won't because we're going to swap things around so calling ReceiveMessage: calls this method while calling replacementReceiveMessage: calls the old version.

The second step is to use the runtime functions to actually perform the swap. The advantage of using a category is that you can use load in the category to do the work:

+ (void)load {
    SEL originalSelector = @selector(ReceiveMessage:);
    SEL overrideSelector = @selector(replacementReceiveMessage:);
    Method originalMethod = class_getInstanceMethod(self, originalSelector);
    Method overrideMethod = class_getInstanceMethod(self, overrideSelector);
    if (class_addMethod(self, originalSelector, method_getImplementation(overrideMethod), method_getTypeEncoding(overrideMethod))) {
            class_replaceMethod(self, overrideSelector, method_getImplementation(originalMethod), method_getTypeEncoding(originalMethod));
    } else {
            method_exchangeImplementations(originalMethod, overrideMethod);
    }
}

There are two cases that need to be handled:

  • If the method we're swizzling is actually defined in a superclass, we have to use class_addMethod to add an implementation of ReceiveMessage: to the target class, which we do using our replacement implementation. Then we can use class_replaceMethod to replace replacementReceiveMessage: with the superclass's implementation, so our new version will be able to correctly call the old.
  • If the method is defined in the target class, class_addMethod will fail but then we can use method_exchangeImplementations to just swap the new and old versions.

这篇关于如何实现方法swizzling?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆