iOS 黑魔法 - Method Swizzling实现原理

2021-10-13  本文已影响0人  smile_frank

Method Swizzling

Method Swizzling,顾名思义,就是交换两个 方法的实现。简单来说,就是利用Objective-C Runtime的动态绑定特性,将一个方法的实现与另 一个方法的实现进行交换。

objc_class

在Objective-C的Runtime中,一个类是用一个名为objc_class的 结构体表示的,它的定义如下:

objc_method_list

我们从上述结构体中可以发现一 个objc_method_list指针,它保存着当前类的所有方法列表。同 时,objc_method_list也是一个结构体,它的定义如下:

objc_method

我们从上面的结构体中发现一个objc_method字段,它的定义如下:


我们从上面的结构体中还发现,一个方法由如下三部分组成。

交换原理

使用Method Swizzling交换方法,其实就是修改了objc_method 结构体中的mthod_imp,即改变了method_name和method_imp的映射关系如下:


实现Method Swizzling的相关函数

Method class_getInstanceMethod(Class_Nullable aClass,SEL_Nonnull aSelector) OBJC_AVAILABLE(10.0,2.0,9.0,1.0,2.0);

BOOL class_addMethod(Class_Nullable aClass,SEL_Nonnull aSelector,IMP_Nonnullimp,const char * _Nullable types) OBJC_AVAILABLE(10.5,2.0,9.0,1.0,2.0);

注意点 返回成功,说明已经成功在目标类中添 加了该方法;返回失败,说明在目标类中已经存 在相同方法名的方法。

IMP method_getImplementation(Method_Nonnull method) OBJC_AVAILABLE (10.5,2.0,9.0,1.0,2.0);

IMP class_replaceMethod(Class_Nullable aClass,SEL_Nonnull aSelector,IMP_Nonnull imp,const char * _Nullable types) OBJC_AVAILABLE(10.5,2.0,9.0,1.0,2.0);

void method_exchangeImplementations(Method_Nonnull m1,Method_Nonnull m2) OBJC_AVAILABLE(10.5,2.0,9.0,1.0,2.0);

#import <objc/runtime.h>

@implementation NSObject (Swizzler)


+ (BOOL)sensorsdata_swizzleMethod:(SEL)originalSEL withMethod:(SEL)alternateSEL {
   
    //获取原始的方法
    Method originalMethod = class_getInstanceMethod(self, originalSEL);
    if (!originalMethod) {
        return NO;
    }
    //获取将要交换的方法
    Method alternateMethod = class_getInstanceMethod(self, alternateSEL);
    if (!alternateMethod) {
        return NO;
    }
    //交互两个方法的实现
    method_exchangeImplementations(originalMethod, alternateMethod);
    //返回yes,方法交换成功
    return YES;
}

@end

上一篇下一篇

猜你喜欢

热点阅读