问题场景:如何统一修改viewController中的viewDidLoad方法,添加一句打印操作?
一、Method Swizzling解决
1、在viewController的分类中新增viewDidLoaded方法,方法内部调用类的viewDidLoad方法,并增加NSLog方法。
2、使用method_exchangeImplementation()交换viewDidLoaded和viewDidLoad方法。
#import "UIViewController+Print.h" #import <objc/runtime.h> @implementation UIViewController (Print) - (void)viewDidLoaded{ [self viewDidLoaded]; NSLog(@"Beche: %@ did load", self); } + (void)load{ static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ Method viewDidLoad = class_getInstanceMethod(self, @selector(viewDidLoad)); Method viewDidLoaded = class_getInstanceMethod(self, @selector(viewDidLoaded)); method_exchangeImplementations(viewDidLoad, viewDidLoaded); }); } @end
二、IMP解决
1、新建viewController的分类。
2、取得原始方法的IMP(implementation)指针。
3、重新设置方法实现。
typedef void (*_VIMP)(id,SEL,...); // 无返回值,有参数的IMP typedef id (*_IMP)(id,SEL,...); // 有返回值,有参数的IMP @implementation UIViewController (Print) + (void)load{ static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ // 获取原始方法 Method viewDidLoad = class_getInstanceMethod(self, @selector(viewDidLoad)); // 获取原始方法实现 _VIMP viewDidLoad_IMP = (_VIMP)method_getImplementation(viewDidLoad); method_setImplementation(viewDidLoad, imp_implementationWithBlock(^(id target,SEL action){ // 调用原始方法实现 viewDidLoad_IMP(target,@selector(viewDidLoad)); // 增加代码 NSLog(@"Beche: %@ did load", target); })); }); } @end