objective-c - 如何实现方法调配?

标签 objective-c cocoa methods swizzling simbl

我正在尝试使用 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_addMethodReceiveMessage: 的实现添加到目标类,我们使用我们的替换实现。然后我们可以使用 class_replaceMethodreplacementReceiveMessage: 替换为父类(super class)的实现,这样我们的新版本就可以正确调用旧版本。
  • 如果方法是在目标类中定义的,class_addMethod 将失败,但我们可以使用 method_exchangeImplementations 来交换新旧版本。

关于objective-c - 如何实现方法调配?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5371601/

相关文章:

java - 在java中使用方法返回

javascript - 将原型(prototype)/方法添加到 jQuery val();

objective-c - 将 .NET 中的 DateTime 对象格式化为 objective-c 的 NSDate

objective-c - 跨多个类文件使用代码

ios - 如何知道cocos2d中的触摸持续时间?

swift - 将 WebView 保存为 PDF 会返回空白图像吗?

cocoa - 适用于 Mac App Store 的 Package Automator Action

ios - 在 iOS 上移动或复制大文件(> 100 MB)的最可靠方法是什么?

macos - NSTableView编辑列:row:withEvent:select: does not tab properly?

来自 IEnumerable<KeyValuePair<int, string>> 的通用 GetOnlyKeys 的 C# 扩展方法