加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

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

发布时间:2020-12-16 05:51:39 所属栏目:百科 来源:网络整理
导读:我正在尝试修改一个程序的行为(我没有它的源)使用SIMBL.我使用类转储,发现我需要覆盖一个实例方法 这个方法在类中叫做控制器.我需要做的就是获得arg1的参数.也许NSLog它或发布通知… 我读了关于方法在目标c中的旋转,但是如何使用它?我需要参考我没有的课程M
我正在尝试修改一个程序的行为(我没有它的源)使用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来交换新旧版本.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读