从方法调用说起
OC的方法调用,也叫消息发送.对于OC的方法调用[receiver message];
,编译器会转化成以下调用:
objc_msgSend(receiver, selector);
如果有多个消息参数,如:[receiver message:arg1 arg2:arg2 arg3:arg3 ....];
则转化为:
objc_msgSend(receiver, selector, arg1, arg2, arg3, ...);
我们可以用clang -rewrite-objc
命令将OC代码转换成C++代码,具体参考附录1
什么是runtime?
OC是一门动态语言,与C++这种静态语言不同,静态语言的各种数据结构在编译期已经决定了,不能够被修改。而动态语言却可以使我们在程序运行期,动态的修改一个类的结构,如修改方法实现,绑定实例变量等。
OC作为动态语言,它总会想办法将静态语言在编译期决定的事情,推迟到运行期来做。所以,仅有编译器是不够的,它需要一个运行时系统(runtime system),这也就是OC的runtime系统的意义,它是OC运行框架的基石。
附录
附录1: clang -rewrite-objc:将OC代码转换成C++代码
Clang 编译器通过以下命令可以将OC代码转换成C++代码:
clang -rewrite-objc inputfile
如以下代码(main.m
):
<font color=red>内容</font>
@interface Person : NSObject
@property(nonatomic,strong) NSString * name;
@end
@implementation Person
-(void) sayHello{
NSLog(@"@Hello %@",self.name);
}
@end
int main(int argc, const char * argv[]) {
Person * person = [[Person alloc]init];
person.name = @"Sammy Lan";
[person sayHello];
return 0;
}
通过执行-rewrite-objc main.m
生成main.cpp
文件:
#ifndef _REWRITER_typedef_Person
#define _REWRITER_typedef_Person
typedef struct objc_object Person;
typedef struct {} _objc_exc_Person;
#endif
extern "C" unsigned long OBJC_IVAR_$_Person$_name;
struct Person_IMPL {
struct NSObject_IMPL NSObject_IVARS;
NSString *_name;
};
// @property(nonatomic,strong) NSString * name;
/* @end */
// @implementation Person
static void _I_Person_sayHello(Person * self, SEL _cmd) {
NSLog((NSString *)&__NSConstantStringImpl__var_folders_mv_r6qfhyyn59n3lprfy6qyhjrh0000gn_T_main_b2bce8_mi_0,((NSString *(*)(id, SEL))(void *)objc_msgSend)((id)self, sel_registerName("name")));
}
static NSString * _I_Person_name(Person * self, SEL _cmd) { return (*(NSString **)((char *)self + OBJC_IVAR_$_Person$_name)); }
static void _I_Person_setName_(Person * self, SEL _cmd, NSString *name) { (*(NSString **)((char *)self + OBJC_IVAR_$_Person$_name)) = name; }
// @end
int main(int argc, const char * argv[]) {
Person * person = ((Person *(*)(id, SEL))(void *)objc_msgSend)((id)((Person *(*)(id, SEL))(void *)objc_msgSend)((id)objc_getClass("Person"), sel_registerName("alloc")), sel_registerName("init"));
((void (*)(id, SEL, NSString *))(void *)objc_msgSend)((id)person, sel_registerName("setName:"), (NSString *)&__NSConstantStringImpl__var_folders_mv_r6qfhyyn59n3lprfy6qyhjrh0000gn_T_main_b2bce8_mi_1);
((void (*)(id, SEL))(void *)objc_msgSend)((id)person, sel_registerName("sayHello"));
return 0;
}
网友评论