class_replaceMethod和method_excha
2020-03-30 本文已影响0人
_RG
class_replaceMethod
是替换某个类的方法的实现,功能上可以替代class_addMethod
, 但是class_addMethod
只能在SEL
没有IMP
指向时才可以添加成功,而class_replaceMethod
不管SEL
有没有`IMP实现,都可以添加成功
当使用class_replaceMethod替换父类的方法时,只有在子类里面调用才有效,实际上是在子类里面重写了父类的方法
例如
@interface User : NSObject
- (void)test;
@end
@implementation User
- (void)test {
NSLog(@"%s",__func__);
}
@end
@interface VIPUser : User
@end
void VIPTest(id obj,SEL _cmd){
NSLog(@"VIPTest");
}
@implementation VIPUser
+ (void)load {
//此方法来自于父类
SEL sel = @selector(test);
//这句话实际是子类重写父类的test方法,用VIPTest test来实现
class_replaceMethod([self class], sel, (IMP)VIPTest, "v@:");
}
@end
method_exchangeImplementations 是交换方法的实现,当获取的方法来自于父类时,也会照成父类调用时被触发, 交换方法的实现,由于方法的实现来自于父类,所以实际是交换的父类的方法的实现
class_getInstanceMethod获取方法时,如果本类没有,则会去父类去寻找
@interface User : NSObject
- (void)test;
@end
@implementation User
- (void)test {
NSLog(@"%s",__func__);
}
@end
@interface VIPUser : User
@end
@implementation VIPUser
+ (void)load {
SEL originalSelector = @selector(test);
SEL swizzledSelector = @selector(vip_test);
Method originalMethod = class_getInstanceMethod([self class], originalSelector);
Method swizzledMethod = class_getInstanceMethod([self class], swizzledSelector);
method_exchangeImplementations(originalMethod, swizzledMethod);
}
- (void)vip_test {
NSLog(@"%s",__func__);
}
@end