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

来源:互联网 发布:java实现语音聊天 编辑:程序博客网 时间:2024/05/02 18:11
顾名思义,就用一个方法替换一个方法的意思:

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

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

首先声明交换方法
#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));
}


原创粉丝点击