微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

objective-c – 如何实现方法swizzling?

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

这个方法在类中叫做控制器.我需要做的就是获得arg1的参数.也许NSLog它或发布通知
我读了关于方法在目标c中的旋转,但是如何使用它?我需要参考我没有的课程MessageController.

谢谢!

解决方法

我猜你在做NSLog之后需要调用原来的实现;如果没有,您可能只能使用类上的类来覆盖该方法.

要打开方法,首先需要一个替换方法.我通常把这样的东西放在目标类的类别中:

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

看起来它会递归调用自身,但它不会因为我们要交换所有东西,所以调用ReceiveMessage:调用这个方法,同时调用replacementReceiveMessage:调用旧版本.

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

+ (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);
    }
}

有两种情况需要处理:

>如果我们正在开发的方法实际上是在一个超类中定义的,那么我们必须使用class_addMethod将一个ReceiveMessage的实现添加到目标类中,我们使用我们的替换实现.那么我们可以使用class_replaceMethod来替换replaceReceiveMessage:与超类的实现,所以我们的新版本将能够正确地调用旧的.>如果方法在目标类中定义,class_addMethod将失败,但是我们可以使用method_exchangeImplementations来交换新旧版本.

原文地址:https://www.jb51.cc/c/113566.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐