iOS 运行时动态交换两个方法(Method-Swizzling)

一、Method-Swizzling 的原理

  • Method-Swizzling 就是交换两个 方法的实现。简单来说,就是利用Objective-C Runtime的动态绑定特性,将一个方法的实现与另 一个方法的实现进行交换。
    iOS 运行时动态交换两个方法(Method-Swizzling)_第1张图片
  • 交换原理:使用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 方法。
  • 因此打印结果就是如此。

你可能感兴趣的:(ios,objective-c,xcode)