void swizzling_method(Class class,SEL orignSelector,SEL newSelector)
{
Method originM = class_getInstanceMethod(class, orignSelector);
Method newM = class_getInstanceMethod(class, newSelector);
if (class_addMethod(class, orignSelector, method_getImplementation(newM), method_getTypeEncoding(newM)))
{
class_replaceMethod(class, newSelector, method_getImplementation(originM), method_getTypeEncoding(originM));
}
else
{
method_exchangeImplementations(originM, newM);
}
}
首先从外部传进来你所要被替换和替换的selector,调用class_getInstanceMethod
方法取到它们的method,在if判断里面,调用class_addMethod
判断一下orignSelector
是不是在这个类里面实现了,如果在其父类里实现了,那class_getInstanceMethod
返回的是父类方法,那我们最后替换掉的是父类的方法,这并不是我们想要得到的结果。如果已经存在,再用method_exchangeImplementations
方法用新方法替换掉原方法。
这个替换方法可以替换自定义的方法和系统方法。
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
NSLog(@"viewDidLoad");
}
- (void)swizzling_viewDidLoad
{
NSLog(@"swizzling_viewDidLoad");
}
+ (void)load
{
swizzling_method(self, @selector(test), @selector(swizzling_viewDidLoad));
}
比如我在一个ViewControl里面使用swizzling_viewDidLoad
替换掉系统的viewDidLoad
,运行一下程序
替换完成!