项目中,拥有这中需求的类应该不止一个,所以我将交换函数实现的功能,放在NSObject分类中。这样哪个类需要,就在自己分类中的类方法发load中实现即可。下面举了UIViewController和UIControl俩个类的交换函数实现。
// // NSObject+AOP.h // #import <Foundation/Foundation.h> @interface NSObject (AOP) /** 交换方法名对应的实现 @param newSelector 新方法名 @param oldSelector 老方法名 */ +(void)exChangeMethodImpWithNewSelctor:(SEL)newSelector oldSelctor:(SEL)oldSelector; @end // // NSObject+AOP.m // #import "NSObject+AOP.h" #import <objc/runtime.h> @implementation NSObject (AOP) /** 交换方法名对应的实现(这样所有的NSObject子类都可以调用,谁调用self就是谁) @param newSelector 新选择器方法名 @param oldSelector 老选择器方法名 */ +(void)exChangeMethodImpWithNewSelctor:(SEL)newSelector oldSelctor:(SEL)oldSelector{ Method newMethod = class_getInstanceMethod([self class], newSelector); Method oldMethod = class_getInstanceMethod([self class], oldSelector); method_exchangeImplementations(newMethod, oldMethod); } @end // // UIViewController+AOP.h // #import <UIKit/UIKit.h> @interface UIViewController (AOP) @end // // UIViewController+AOP.m // #import "UIViewController+AOP.h" #import "NSObject+AOP.h" @implementation UIViewController (AOP) //系统在加载类的时候,会自动调用load方法,且只调用一次。所以,在这里做aop操作。 +(void)load{ SEL newSelector = @selector(aop_viewWillAppear:); SEL oldSelector = @selector(viewWillAppear:); [self exChangeMethodImpWithNewSelctor:newSelector oldSelctor:oldSelector]; } -(void)aop_viewWillAppear:(BOOL)animated{ NSLog(@"替换后是%s", __func__); //调用原来实现 [self aop_viewWillAppear:animated]; } @end // // UIControl+AOP.h // #import <UIKit/UIKit.h> @interface UIControl (AOP) @end // // UIControl+AOP.m // #import "UIControl+AOP.h" #import "NSObject+AOP.h" @implementation UIControl (AOP) //系统在加载类的时候,会自动调用load方法,且只调用一次。所以,在这里最aop操作。 +(void)load{ SEL newSelector = @selector(aop_sendAction:to:forEvent:); SEL oldSelector = @selector(sendAction:to:forEvent:); [self exChangeMethodImpWithNewSelctor:newSelector oldSelctor:oldSelector]; } - (void)aop_sendAction:(SEL)action to:(id)target forEvent:(UIEvent *)event{ NSLog(@"替换后是%s", __func__); //调用原来实现 [self aop_sendAction:action to:target forEvent:event]; } @end