经过了,总要留些痕迹 - iOS原理

C++的this和Objective-C的self

2019-12-06  本文已影响0人  Dylan_J

C++中定义类的实例方法如下:

void MyClass::method(int arg) {
    printf("%p %d\n",this, args);
}

C++编译器将该方法作为C语言函数来处理

void __ZN7MyClass6methodEi(MyClass *this, int arg); {
    printf("%p %d\n", this, arg);
}

MyClass::method方法的实质是__ZN7MyClass6methodEi函数。“this”作为第一个参数传递出去。该方法的调用如下:

MyClass cls;
cls.method(10);

该代码通过C++编译器转换成C语言函数调用的形式:

struct MyClass cls;
__ZN7MyClass6methodEi(&cls, 10);

即this就是MyClass类(结构体)的实例。
同样,我们也来看一下Objective-C的实例方法:

- (void)method:(int)arg {
    NSLog(@"%p %d\n", self, arg);
}

Objective-C编译器同C++的方法一样,也将该方法作为C语言的函数来处理。

void _I_MyObject_method_(struct MyObject *self, SEL _cmd, int arg) {
    NSLog(@"%p %d\n",self arg);
}

与C++中变换结果的this相同,“self”作为第一个参数被传递过去。

MyObject *obj = [[MyObject alloc] init];
[obj method:10];

如果使用clang的-rewrite-objc选项,则上面源码转成:

MyObject *obj = objc_msgSend(
    objc_getClass("MyObject"),sel_registerName("alloc");
);
objc = objc_msgSend(obj, sel_registerName("init"));
objc_msgSend(obj, sel_registerName("method:"), 10);

objc_msgSend函数根据指定的对象和函数名,从对象持有类的结构体中检索I_MyObject_method函数的指针并调用。此时,objc_msgSend函数的第一个参数obj作为I_MyObject_method函数的第一个参数self进行传递。同C++一样,self就是MyObject类的对象。

上一篇下一篇

猜你喜欢

热点阅读