一、Method-Swizzling 的原理
- Method-Swizzling 就是交换两个 方法的实现。简单来说,就是利用Objective-C Runtime的动态绑定特性,将一个方法的实现与另 一个方法的实现进行交换。
- 交换原理:使用Method Swizzling交换方法,其实就是修改了对象方法 结构体中的方法实现。调用方法selector1执行的是IMP1函数,更换后调用selector1执行的就变成了IMP2。
二、代码演示流程
1、首先创建个继承NSObject的类,.h文件声明两个实例方法test1、test2:
@interface MethodSwizzling : NSObject
- (void)test1;
- (void)test2;
@end
2、在.m文件中实现这两个方法,并交换两个方法的实现:
#import "MethodSwizzling.h"
#import <objc/runtime.h>
@implementation MethodSwizzling
// load方法是应用程序把这个类加载到内存的时候调用,而且只会调用一次,所以在这个方法中实现方法的交换最合适
+ (void)load {
// 获取test1、test2方法
Method method_test1 = class_getInstanceMethod(self, @selector(test1));
Method method_test2 = class_getInstanceMethod(self, @selector(test2));
// 交换两个方法的实现
method_exchangeImplementations(method_test1, method_test2);
}
-(void)test1 {
NSLog(@"test1");
}
-(void)test2 {
// 实际调用test1函数
[self test2];
NSLog(@"test2");
}
3、其他地方调用test1方法:
MethodSwizzling *obj = [[MethodSwizzling alloc]init];
[obj test1];
输出结果:
2022-06-27 16:01:47.613741+0800 MethodSwizzling[7284:360599] test1
2022-06-27 16:01:47.613961+0800 MethodSwizzling[7284:360599] test2
- 由此可知,应用程序把这个类加载到内存的时候,也就是说执行完 load 方法后,就已经将两个方法进行交换了。
- 当执行 [obj test1] 方法时,实际执行的是 test2 方法。
- 此时在 test2 方法中又执行 [self test2],实际上又是调用的 test1 方法。
- 因此打印结果就是如此。