1、同一个类中两个方法交换
交换方法
- (void)setBadgeValue:(NSString *)badgeValue 和 - (void)wb_setBadgeValue:(NSString *)badgeValue的实现
@implementation UITabBarItem (BadgeValueImage) + (void)load{ static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ Class clazz = [self class]; // 获取到原来的方法与需要交互的SEL SEL originalSelector = @selector(setBadgeValue:); SEL swizzledSelector = @selector(wb_setBadgeValue:); // 通过SEL 获取到类身上的Method Method originalMethod = class_getInstanceMethod(clazz, originalSelector); Method swizzledMethod = class_getInstanceMethod(clazz, swizzledSelector); // 向类身上添加方法 BOOL result = class_addMethod(clazz, swizzledSelector, method_getImplementation(swizzledMethod), method_getTypeEncoding(swizzledMethod)); if (result) { // 如果添加成功就替换方法实现 class_replaceMethod(clazz, originalSelector, method_getImplementation(swizzledMethod), method_getTypeEncoding(swizzledMethod)); }else{ // 没有添加成功,直接交换方法实现 method_exchangeImplementations(originalMethod, swizzledMethod); } }); } - (void)wb_setBadgeValue:(NSString *)badgeValue{ //调用父类 [self wb_setBadgeValue:badgeValue]; // 实现逻辑 // 如果badgeValue为nil 的话。直接返回 if(!badgeValue){ return; } // 我们直接能够拿到的就是WBTabBar UITabBarController *target = [self valueForKeyPath:@"_target"]; for (UIView *tabBarChild in target.tabBar.subviews) { //找UITabBarButton if ([tabBarChild isKindOfClass:NSClassFromString(@"UITabBarButton")]) { for (UIView *tabBarButtonChild in tabBarChild.subviews) { if ([tabBarButtonChild isKindOfClass:NSClassFromString(@"_UIBadgeView")]) { for (UIView *badgeViewChild in tabBarButtonChild.subviews) { if ([badgeViewChild isKindOfClass:NSClassFromString(@"_UIBadgeBackground")]) { //NSLog(@"终于找到你,还好没放弃"); unsigned int count;//获取完成之后,count的值就代码当前类身上成员变量的个数 //获取类身上的成员变量 Ivar *vars = class_copyIvarList(NSClassFromString(@"_UIBadgeBackground"), &count); //遍历查看 for (int i=0; i<count; i++) { Ivar var = vars[i]; //获取var的名字 NSString *name = [NSString stringWithCString:ivar_getName(var) encoding:NSUTF8StringEncoding]; //获取类型 NSString *type = [NSString stringWithCString:ivar_getTypeEncoding(var) encoding:NSUTF8StringEncoding]; NSLog(@"%@=====%@",name,type); // if ([name isEqualToString:@"_image"]) { //通过kvc赋值 [badgeViewChild setValue:[UIImage imageNamed:self.badgeImageName] forKeyPath:name]; } } //释放内存 free(vars); } } } } } } }
2、交换两个类中某个方法的实现
交换 Person类中 - (void)personEat; 和Dog类中 - (void)dogEat; 中的实现
Person.h
#import <Foundation/Foundation.h> @interface Person : NSObject - (void)personEat; @end
person.m
#import "Person.h" #import "Dog.h" #import <objc/runtime.h> @implementation Person + (void)load{ static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ //1,拿着class Class personClass = [self class]; Class dogClass = [Dog class]; //2.获取两个方法的sel SEL originalSEL = @selector(personEat); SEL swizzledSEL = @selector(dogEat); //3.通过sel获取到class身上的method Method originalMethod = class_getInstanceMethod(personClass, originalSEL); Method swizzledMethod = class_getInstanceMethod(dogClass, swizzledSEL); //4执行方法添加-->添加方法是添加的其他类里面的方 BOOL result = class_addMethod(personClass, swizzledSEL, method_getImplementation(swizzledMethod), method_getTypeEncoding(swizzledMethod)); //5如果添加成功,就把添加的方法的实现与原来的方法进行替换 if (result) { class_replaceMethod(personClass, originalSEL, method_getImplementation(swizzledMethod), method_getTypeEncoding(swizzledMethod)); }else{ //6.如果添加不成功,就直接交换方法实现 method_exchangeImplementations(originalMethod, swizzledMethod); } }); } - (void)personEat{ NSLog(@"人在吃东西"); } @end
Dog.h
#import <Foundation/Foundation.h> @interface Dog : NSObject - (void)dogEat; @end
Dog.m
#import "Dog.h" @implementation Dog - (void)dogEat{ NSLog(@"狗在吃东西"); } @end
此时调用
Person *p = [[Person alloc]init];
[p personEat];
结果会是:狗在吃东西