iOS Method Swizzling
前言
有个奇怪的需求:每个UIViewController在viewDidAppear:和viewWillAppear:方法中都需要执行一些操作。这里介绍一种iOS Method Swizzling方法:让viewDidAppear:和customViewDidAppear:方法调换实现方式;让viewWillAppear:和customViewWillAppear:方法调换实现方式。
实现过程
- 新建UIViewController的一个category - Swizzle
- 在Swizzle中实现customViewDidAppear:方法和customViewWillAppear:方法。
- 并且重写
load
方法,在load方法中将指向viewDidAppear:实现的指针和指向customViewDidAppear:实现的指针对调;将指向viewWillAppear:实现的指针和指向customViewWillAppear:实现的指针对调
- 函数指针对调实现
- 在AppDelegate.m中import这个Swizzle category。那么在所有的UIViewController执行load方法时都会执行Swizzle中重写的load方法,以实现方法的对调;所以之后正常调用viewDidAppear:或是viewWillAppear:时,其实是调用的customViewDidAppear:和customViewWillAppear:方法
具体代码实现
Swizzle category
@implementation UIViewController (Swizzle) + (void)load { swizzleAllViewController(); } - (void)customViewDidAppear:(BOOL)animated { // do something here [self customViewDidAppear:animated]; // 其实是调用的viewDidAppear: } - (void)customviewWillAppear:(BOOL)animated { // do something here [self customviewWillAppear:animated]; // 其实是调用的viewWillAppear: } @end // 函数指针对调 void swizzleAllViewController() { Swizzle([UIViewController class], @selector(viewDidAppear:), @selector(customViewDidAppear:)); //Swizzle([UIViewController class], @selector(viewWillDisappear:), @selector(customViewWillDisappear:)); Swizzle([UIViewController class], @selector(viewWillAppear:), @selector(customviewWillAppear:)); }
函数指针对调的实现
void Swizzle(Class c, SEL origSEL, SEL newSEL) { Method origMethod = class_getInstanceMethod(c, origSEL); Method newMethod = nil; if (!origMethod) { origMethod = class_getClassMethod(c, origSEL); if (!origMethod) { return; } newMethod = class_getClassMethod(c, newSEL); if (!newMethod) { return; } } else { newMethod = class_getInstanceMethod(c, newSEL); if (!newMethod) { return; } } if (class_addMethod(c, origSEL, method_getImplementation(newMethod), method_getTypeEncoding(newMethod))) { NSLog(@"vanney code log... errorhappened"); class_replaceMethod(c, newSEL, method_getImplementation(origMethod), method_getTypeEncoding(origMethod)); } else { method_exchangeImplementations(origMethod, newMethod); } }
P.S
以上代码都参考自Coding-iOS