runtime-Method Swizzling(方法调换)
通过修改一个已存在类的方法, 来实现方法替换是比较常用的runtime技巧。
使所有的类都具有调换方法的功能:
#import <Foundation/Foundation.h>
@interface NSObject (SwzillingMethod)
+ (void)swzillingOriginSel:(SEL)originSel withSwizzlingSel:(SEL)newSel;
@end
#import "NSObject+SwzillingMethod.h"
#import <objc/runtime.h>
@implementation NSObject (SwzillingMethod)
+ (void)swzillingOriginSel:(SEL)originSel withSwizzlingSel:(SEL)newSel{
Method originM =class_getInstanceMethod([self class], originSel);
Method newM=class_getInstanceMethod([self class], newSel);
method_exchangeImplementations(originM, newM); // 方法调换
}
@end
需求:调换UIViewController类系统的ViewWillAppear方法,自定义ViewWillAppear方法
#import <UIKit/UIKit.h>
@interface UIViewController (ViewWillAppear)
@end
#import "UIViewController+ViewWillAppear.h"
#import "NSObject+SwzillingMethod.h"
@implementation UIViewController (ViewWillAppear)
+ (void)load{
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
[self swzillingOriginSel:@selector(viewWillAppear:) withSwizzlingSel:@selector(zn_viewWillAppear:)];
});
}
// 自定义ViewWillAppear方法的实现
- (void)zn_viewWillAppear:(BOOL)animated{
// 实现部分自定义,需要在UIViewController类的ViewWillAppear方法中做什么就写啥
NSString*name =NSStringFromClass([self class]);
// 实现:使得类名为ViewController的类中视图背景色为红色
if([name isEqualToString:@"ViewController"]){
self.view.backgroundColor= [UIColorredColor];
}
//这个一定要切记切记切记!(与重写ViewWillAppear方法类似)
[self zn_viewWillAppear:animated];
}
@end