-
Notifications
You must be signed in to change notification settings - Fork 43
/
HYBMsgSend.m
99 lines (80 loc) · 3.51 KB
/
HYBMsgSend.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
//
// HYBMsgSend.m
// RuntimeDemo
//
// Created by huangyibiao on 16/1/2.
// Copyright © 2016年 huangyibiao. All rights reserved.
//
#import "HYBMsgSend.h"
#import <objc/runtime.h>
#import <objc/message.h>
#import <UIKit/UIKit.h>
@implementation HYBMsgSend
- (void)noArgumentsAndNoReturnValue {
NSLog(@"%s was called, and it has no arguments and return value", __FUNCTION__);
}
- (void)hasArguments:(NSString *)arg {
NSLog(@"%s was called, and argument is %@", __FUNCTION__, arg);
}
- (NSString *)noArgumentsButReturnValue {
NSLog(@"%s was called, and return value is %@", __FUNCTION__, @"不带参数,但是带有返回值");
return @"不带参数,但是带有返回值";
}
- (int)hasArguments:(NSString *)arg andReturnValue:(int)arg1 {
NSLog(@"%s was called, and argument is %@, return value is %d", __FUNCTION__, arg, arg1);
return arg1;
}
// C函数
int cStyleFunc(id receiver, SEL sel, const void *arg1, const void *arg2) {
NSLog(@"%s was called, arg1 is %@, and arg2 is %@",
__FUNCTION__,
[NSString stringWithUTF8String:arg1],
[NSString stringWithUTF8String:arg1]);
return 1;
}
- (float)returnFloatType {
NSLog(@"%s was called, and has return value", __FUNCTION__);
return 3.121592612321323123;
}
- (CGRect)returnTypeIsStruct {
NSLog(@"%s was called", __FUNCTION__);
return CGRectMake(0, 0, 10, 10);
}
+ (void)test {
// 1.创建对象
HYBMsgSend *msg = ((HYBMsgSend * (*)(id, SEL))objc_msgSend)((id)[HYBMsgSend class], @selector(alloc));
// 2.初始化对象
msg = ((HYBMsgSend * (*)(id, SEL))objc_msgSend)((id)msg, @selector(init));
// 3.调用无参数无返回值方法
((void (*)(id, SEL))objc_msgSend)((id)msg, @selector(noArgumentsAndNoReturnValue));
// 4.调用带一个参数但无返回值的方法
((void (*)(id, SEL, NSString *))objc_msgSend)((id)msg, @selector(hasArguments:), @"带一个参数,但无返回值");
// 5.调用带返回值,但是不带参数
NSString *retValue = ((NSString * (*)(id, SEL))objc_msgSend)((id)msg, @selector(noArgumentsButReturnValue));
NSLog(@"5. 返回值为:%@", retValue);
// 6.带参数带返回值
int returnValue = ((int (*)(id, SEL, NSString *, int))
objc_msgSend)(msg,
@selector(hasArguments:andReturnValue:),
@"参数1",
2016);
NSLog(@"6. return value is %d", returnValue);
NSLog(@"%s", @encode(const void *));
// 7.动态添加方法,然后调用C函数
class_addMethod(msg.class, NSSelectorFromString(@"cStyleFunc"), (IMP)cStyleFunc, "i@:r^vr^v");
returnValue = ((int (*)(id, SEL, const void *, const void *))
objc_msgSend)((id)msg,
NSSelectorFromString(@"cStyleFunc"),
"参数1",
"参数2");
NSLog(@"7. return value is %d", returnValue);
// 8.返回浮点型时,调用objc_msgSend/objc_msgSend_fpret,其结果是一样的。
// float retFloatValue = ((float (*)(id, SEL))objc_msgSend_fpret)((id)msg, @selector(returnFloatType));
// NSLog(@"%f", retFloatValue);
// retFloatValue = ((float (*)(id, SEL))objc_msgSend)((id)msg, @selector(returnFloatType));
// NSLog(@"%f", retFloatValue);
// 9.返回结构体时,不能使用objc_msgSend,而是要使用objc_msgSend_stret,否则会crash
// CGRect frame = ((CGRect (*)(id, SEL))objc_msgSend_stret)((id)msg, @selector(returnTypeIsStruct));
// NSLog(@"9. return value is %@", NSStringFromCGRect(frame));
}
@end