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

前端之家收集整理的这篇文章主要介绍了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来交换新旧版本.

猜你在找的C&C++相关文章