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 OtherPerson
10
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->_cmd
59 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 push
11 #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 Instance
21 //发送消息给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