深入浅出Objective-C Runtime

从方法调用说起

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):
内容

@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;
}

你可能感兴趣的:(深入浅出Objective-C Runtime)