在网上找了一些对Runtime做出解释的文章,最后决定写一个自己的理解,不然知识终究不是自己。
1、首先来创建一个控制台项目,新建一个继承自NSObject的类
@interface people : NSObject
@property (nonatomic, strong) NSString *name;
@property (nonatomic, assign) int age;
@end
在main.m中引用:
<pre name="code" class="objc">int main(int argc, const char * argv[]) {
@autoreleasepool {
people *p = [[people alloc] init];
NSString *str = @"zhangsan";
p.name = str;
[p setName:str];
p.age = 20;
}
return 0;
}
2、进入项目目录,将main.m文件编译成main.cpp
得到
3、对main.cpp进行分析
可以看到前面对OC中的各种对象结构进行了声明,暂时不管,直接跳到main函数部分:
#ifndef _REWRITER_typedef_people
#define _REWRITER_typedef_people
typedef struct objc_object people;
typedef struct {} _objc_exc_people;
#endif
struct people_IMPL {
struct NSObject_IMPL NSObject_IVARS;
};
// @property (nonatomic, strong) NSString *name;
// @property (nonatomic, assign) int age;
/* @end */
int main(int argc, const char * argv[]) {
/* @autoreleasepool */ { __AtAutoreleasePool __autoreleasepool;
people *p = ((people *(*)(id, SEL))(void *)objc_msgSend)((id)((people *(*)(id, SEL))(void *)objc_msgSend)((id)objc_getClass("people"), sel_registerName("alloc")), sel_registerName("init"));
NSString *str = (NSString *)&__NSConstantStringImpl__var_folders_nf_r6j09lpx2k1b646yy591zhh40000gn_T_main_e4d98c_mi_0;
((void (*)(id, SEL, NSString *))(void *)objc_msgSend)((id)p, sel_registerName("setName:"), (NSString *)str);
((void (*)(id, SEL, NSString *))(void *)objc_msgSend)((id)p, sel_registerName("setName:"), (NSString *)str);
((void (*)(id, SEL, int))(void *)objc_msgSend)((id)p, sel_registerName("setAge:"), 20);
}
return 0;
}
static struct IMAGE_INFO { unsigned version; unsigned flag; } _OBJC_IMAGE_INFO = { 0, 2 };
简单的对比,就能看出:
1)OC通过objc_msgSend()给对象发送消息,来实现动态调用。
2)OC通过objc_getClass("people")来获得指定名称的对象。
3)OC通过sel_registerName("alloc")可以调用对象的方法。
总结一下就是:使用objc_msgSend函数,给objc_getClass函数实例化的对象发送sel_registerName获取到的方法
这么一个消息 。