- 利用oc运行时特性,进行方法交换,一般是把一些类方法交换成我们自己的方法,或者修改一些SDK的一些方法等.
methodSwizzling方法封装.创建一个NSObject类别,吧方法封装一下.,以后直接拿来用就可以了
#import "NSObject+Swizzing.h"
#import <objc/runtime.h>
@implementation NSObject (Swizzing)
+ (void)methodSwizzlingWithOriginalSelector:(SEL)originalSelector bySwizzledSelector:(SEL)swizzledSelector{
Class class = [self class];
//原有方法
Method originalMethod = class_getInstanceMethod(class, originalSelector);
//替换原有方法的新方法
Method swizzledMethod = class_getInstanceMethod(class, swizzledSelector);
//先尝试給源SEL添加IMP,这里是为了避免源SEL没有实现IMP的情况
BOOL didAddMethod = class_addMethod(class,originalSelector,
method_getImplementation(swizzledMethod),
method_getTypeEncoding(swizzledMethod));
if (didAddMethod) {//添加成功:说明源SEL没有实现IMP,将源SEL的IMP替换到交换SEL的IMP
class_replaceMethod(class,swizzledSelector,
method_getImplementation(originalMethod),
method_getTypeEncoding(originalMethod));
} else {//添加失败:说明源SEL已经有IMP,直接将两个SEL的IMP交换即可
method_exchangeImplementations(originalMethod, swizzledMethod);
}
}
@end
- 做一个小用法举例说明
比如你在用button的setBackgroundColor:方法设置颜色时,你想同时把button的title设置了.那么你就可以用自己的方法swizz_setBackgroundColor:去交换系统的setBackgroundColor:方法.具体使用时创建一个button的类别,在+(void)load方法中去进行方法交换.
#import "UIButton+Change.h"
#import "NSObject+Swizzing.h"
@implementation UIButton (Change)
+ (void)load
{
static dispatch_once_t oneToken;
dispatch_once(&oneToken, ^{
[self methodSwizzlingWithOriginalSelector:@selector(setBackgroundColor:) bySwizzledSelector:@selector(swizz_setBackgroundColor:)];
});
}
- (void)swizz_setBackgroundColor:(UIColor *)backgroundColor
{
NSLog(@"交换了");
//相当于调了原方法(其实已经交换过来了)
[self swizz_setBackgroundColor:backgroundColor];
[self setTitle:@"点我" forState:UIControlStateNormal];
}
@end
网友评论