方法替换:-实现拦截功能

本文介绍了Objective-C中的方法替换(Method Swizzling),通过示例代码展示了如何使用方法替换来实现拦截功能,包括使用分类扩展和在本类方法间进行替换。还提到了在工程中使用方法拦截后恢复原始方法的重要性,并给出了一种宏定义的实现方式。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

顾名思义,就用一个方法替换一个方法的意思:

直接上代码,我自己看英文,也不翻译了,想了解的可以去看文档
点击这里直接看英文文档 
  另外还有好多其他的扩展

在方法替换的过程中,我们可以用分类扩展方法来替换,也可以在本类方法之间的替换

首先声明交换方法
#import </usr/include/objc/objc-class.h>
Void MethodSwizzle(Class aClass, SEL orig_sel, SEL alt_sel)



实现功能:

void  MethodSwizzle(Class aClass, SEL orig_sel, SEL alt_sel)

 {

 Method orig_method = nil, alt_method = nil;

    

// First, look for the methods
    

orig_method = class_getInstanceMethod(aClass, orig_sel);

 alt_method = class_getInstanceMethod(aClass, alt_sel);

    

// If both are found, swizzle them

 if ((orig_method != nil) && (alt_method != nil))
        {
        char *temp1;

 IMP temp2;

 temp1 = orig_method->method_types;


        orig_method->method_types = alt_method->method_types;


        alt_method->method_types = temp1;


        temp2 = orig_method->method_imp;
        

orig_method->method_imp = alt_method->method_imp;
        

alt_method->method_imp = temp2;
        

}


}


当然我们也有自己的方法来实现交换:
void Swizzle(Class c, SEL orig, SEL _new)
{
      MethodorigMethod = class_getInstanceMethod(c, orig);
      MethodnewMethod = class_getInstanceMethod(c, _new);
      if(class_addMethod(c, orig, method_getImplementation(newMethod),method_getTypeEncoding(newMethod)))
              class_replaceMethod(c, _new, method_getImplementation(origMethod),method_getTypeEncoding(origMethod));
      else
            method_exchangeImplementations(origMethod, newMethod);
}

在工程中,经常使用方法拦截之后(方法替换)之后,我们再次把方法替换回来,为了不影响其他模块使用这个系统功能。

可以定义成一个宏:
#define METHODCALLBACK(taget){\
NSString *__Name=NSStringFromSelector(_cmd);\
NSString *_selectorName=[@"__Inv_"stringByAppendingString:__Name];\
Swizzle([self class], NSSelectorFromString(_selectorName),NSSelectorFromString(__Name));\
taget;\
Swizzle([self class], NSSelectorFromString(__Name),NSSelectorFromString(_selectorName));\
}

原型是:
METHODCALLBACK(taget){
NSString *__Name=NSStringFromSelector(_cmd);
NSString *_selectorName=[@"__Inv_"stringByAppendingString:__Name];
Swizzle([self class], NSSelectorFromString(_selectorName),NSSelectorFromString(__Name));
taget;
Swizzle([self class], NSSelectorFromString(__Name),NSSelectorFromString(_selectorName));
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值