1 // 2 // Created by HEYANG on 16/1/11. 3 // Copyright © 2016年 HEYANG. All rights reserved. 4 // 5 6 #import "OtherPerson.h" 7 #import <objc/message.h> 8 9 @implementation OtherPerson10 11 12 +(void)load{13 Class clazz = NSClassFromString(@"Person");14 15 //获取替换前的类方法16 Method instance_eat = 17 class_getClassMethod(clazz, @selector(resolveInstanceMethod:));18 //获取替换后的类方法19 Method instance_notEat = 20 class_getClassMethod(self, @selector(hy_resolveInstanceMethod:));21 22 //然后交换类方法23 method_exchangeImplementations(instance_eat, instance_notEat);24 25 //获取替换前的类方法26 Method class_eat = 27 class_getClassMethod(clazz, @selector(resolveClassMethod:));28 //获取替换后的类方法29 Method class_notEat = 30 class_getClassMethod(self, @selector(hy2_resolveClassMethod:));31 32 //然后交换类方法33 method_exchangeImplementations(class_eat, class_notEat);34 35 }36 37 void eat_1(id self,SEL sel)38 {39 NSLog(@"到底吃不吃饭了");40 NSLog(@"%@ %@",self,NSStringFromSelector(sel));41 }42 void eat_2(id self,SEL sel, NSString* str1,NSString* str2)43 {44 NSLog(@"到底吃不吃饭了");45 NSLog(@"%@ %@",self,NSStringFromSelector(sel));46 NSLog(@"打印两个参数值:%@ and %@",str1,str2);47 }48 49 50 +(BOOL)hy_resolveInstanceMethod:(SEL)sel{51 //当sel为实现方法中 有 eat 方法52 if (sel == NSSelectorFromString(@"eat")) {53 //就 动态添加eat方法54 55 // 第一个参数:给哪个类添加方法56 // 第二个参数:添加方法的方法编号57 // 第三个参数:添加方法的函数实现(函数地址)58 // 第四个参数:函数的类型,(返回值+参数类型) v:void @:对象->self :表示SEL->_cmd59 class_addMethod(self, sel, (IMP)eat_1, "v@:");60 }61 return YES;62 }63 +(BOOL)hy2_resolveClassMethod:(SEL)sel{64 65 if (sel == NSSelectorFromString(@"eat:with:")) {66 67 class_addMethod(objc_getMetaClass("Person"), sel, (IMP)eat_2, "v#:@@");68 }69 70 return YES;71 }72 73 @end
1 /** 2 * 3 * Swap Method and Dynamic add Method (交换方法和动态添加方法) 4 * 5 */ 6 7 #import <Foundation/Foundation.h> 8 9 //ignore undeclared warm 忽视未声明的警告10 #pragma clang diagnostic push11 #pragma clang diagnostic ignored "-Wundeclared-selector"12 13 int main(int argc, const char * argv[]) {14 @autoreleasepool {15 //get this Person class 拿到了这个Person类16 Class clazz = NSClassFromString(@"Person");17 //get this Person Instance 拿到这个Person实例18 id person = [[clazz alloc] init];19 20 //send message to 'eat' method in Person Class or Person Instance21 //发送消息给Person类或者Person实例的‘eat’方法 不含参数22 [person performSelector:@selector(eat) withObject:nil];23 //发送消息给Person类的‘eat’方法 含两个参数24 [clazz performSelector:@selector(eat:with:) 25 withObject:@"Hello" 26 withObject:@"World"];27 }28 return 0;29 }30 31 #pragma clang diagnostic pop