声明一个头文件SwizzleMethod.h

#ifndef SwizzleMethod_h
#define SwizzleMethod_h

#import <objc/runtime.h>

static inline void swizzleInstanceMethod(Class cls, SEL originalSel, SEL swizzledSel) {
    Method originalMethod = class_getInstanceMethod(cls, originalSel);
    Method swizzledMethod = class_getInstanceMethod(cls, swizzledSel);
    if (!originalMethod || !swizzledMethod) {
        return NO;
    }
    // 先尝试給源方法添加实现,这里是为了避免源方法没有实现的情况
    BOOL didAdded = class_addMethod(cls,
                                    originalSel,
                                    method_getImplementation(swizzledMethod),
                                    method_getTypeEncoding(swizzledMethod));
    
    if (didAdded) {// 添加成功:将源方法的实现替换到交换方法的实现
        class_replaceMethod(cls,
                            swizzledSel,
                            method_getImplementation(originalMethod),
                            method_getTypeEncoding(originalMethod));
    } else {// 说明源方法已经有实现,直接将两个方法的实现交换即
        method_exchangeImplementations(originalMethod, swizzledMethod);
    }
    
    return YES;
}

static inline void swizzleClassMethod(Class cls, SEL originalSel, SEL swizzledSel) {
    Method originalMethod = class_getClassMethod(cls, originalSel);
    Method swizzledMethod = class_getClassMethod(cls, swizzledSel);
    if (!originalMethod || !swizzledMethod) {
        return NO;
    }
    
    BOOL didAdded = class_addMethod(objc_getMetaClass([NSStringFromClass(cls) UTF8String]),
                                    originalSel,
                                    method_getImplementation(swizzledMethod),
                                    method_getTypeEncoding(swizzledMethod));
    if (didAdded) {
        class_replaceMethod(objc_getMetaClass([NSStringFromClass(cls) UTF8String]),
                            swizzledSel,
                            method_getImplementation(originalMethod),
                            method_getTypeEncoding(originalMethod));
    } else {
        method_exchangeImplementations(originalMethod, swizzledMethod);
    }
    
    return YES;
}

#endif /* SwizzleMethod_h */

使用了内联函数

方法替换时候,比较严谨的做法,先尝试給源方法添加实现,这里是为了避免源方法没有实现的情况

添加成功:将源方法的实现替换到交换方法的实现

添加失败:说明源方法已经有实现,直接将两个方法的实现交换即