news

对象与方法的本质

2019-04-17  本文已影响0人  Vency_

方法:

通过前面一篇 从 MachO 加载到对象创建! 可以了解到 allocinit 方法的底层, 接下来看方法的实质:

定义类 WXPerson, 包含方法 run;
创建 person 对象:

WXPerson * person = [[WXPerson all] init];
[person run];

通过编译器编译来看对象及方法的实质:
通过终端命令 clang -rewrite-objc main.m 可以获得同级目录下 main.cpp文件, 查看文件发现, 上面创建对象及调用方法被编译成如下代码:
由于代码太长选择图片格式:

可以看到很多类型强转, 去掉类型强转:

WXPerson * person = objc_msgSend(
                                objc_msgSend(
                                            objc_getClass("WXPerson"), 
                                            sel_registerName("alloc")), 
                                sel_registerName("init"));
    objc_msgSend(person, 
                 sel_registerName("run"));

可以看到:

补充: 由于该方法调用非常频繁, 且 C / C++ 方法不能动态保存方法的参数, 需要通过汇编通过寄存器读取动态参数, 所以苹果把该方法用汇编实现(具体见 libobjc.A.dylib -> objc-msg-*.s):
前面文章已有涉及: +load VS +initialize

对象:

查看上面编译好的 main.cpp 文件:

typedef struct objc_object WXPerson;
typedef struct {} _objc_exc_WXPerson;

struct WXPerson_IMPL {
    struct NSObject_IMPL NSObject_IVARS;
};

struct NSObject_IMPL {
    Class isa;
};

可以发现 WXPerson类被编译为 typedef struct objc_object WXPerson 结构体
objc_object 定义如下:

typedef struct objc_class *Class;

struct objc_object {
    Class _Nonnull isa __attribute__((deprecated));
};

typedef struct objc_object *id;

typedef struct objc_selector *SEL;

至此可以看出:

上一篇下一篇

猜你喜欢

热点阅读