我正在尝试使用 SIMBL 修改程序的行为(我没有它的源代码)。我使用了类转储,发现我需要覆盖一个实例方法
此方法位于称为 Controller 的类中。我需要做的就是获取参数 arg1,仅此而已。也许 NSLog 或发布通知... 我在 objective-c 中阅读了 method swizzling,但我该如何使用它呢?。我需要引用我没有类(class)的 MessageController 类。
谢谢!
最佳答案
我猜您需要在完成 NSLog 之后调用原始实现;如果没有,您可以只使用类上的类别来覆盖该方法。
要调配该方法,首先您需要一个替换方法。我通常把这样的东西放在目标类的类别中:
- (void)replacementReceiveMessage:(const struct BInstantMessage *)arg1 {
NSLog(@"arg1 is %@", arg1);
[self replacementReceiveMessage:arg1];
}
这看起来会递归地调用自己,但它不会,因为我们要交换一些东西,所以调用 ReceiveMessage:
会调用 this 方法,同时调用 replacementReceiveMessage:
调用旧版本。
第二步是使用运行时函数实际执行交换。使用类别的好处是您可以在类别中使用load
来完成工作:
+ (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);
}
}
有两种情况需要处理:
- 如果我们调配的方法实际上是在父类(super class)中定义的,我们必须使用
class_addMethod
将ReceiveMessage:
的实现添加到目标类,我们使用我们的替换实现。然后我们可以使用class_replaceMethod
将replacementReceiveMessage:
替换为父类(super class)的实现,这样我们的新版本就可以正确调用旧版本。 - 如果方法是在目标类中定义的,
class_addMethod
将失败,但我们可以使用method_exchangeImplementations
来交换新旧版本。
关于objective-c - 如何实现方法调配?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5371601/