self和super - ShenYj/ShenYj.github.io GitHub Wiki
- self是类的隐藏参数,指向当前调用方法的这个类的实例
- super本质上是一个编译器标识符,和self指向的是同一个消息接受者。不同的是super调用方式的时候,会告诉编译器去调用父类的方法而不是本类的方法。
self和super发送消息方法分别是
objc_msgSend
和objc_msgSendSuper
OBJC_EXPORT void
objc_msgSend(void /* id self, SEL op, ... */ )
OBJC_AVAILABLE(10.0, 2.0, 9.0, 1.0, 2.0);
OBJC_EXPORT void
objc_msgSendSuper(void /* struct objc_super *super, SEL op, ... */ )
OBJC_AVAILABLE(10.0, 2.0, 9.0, 1.0, 2.0);
/// Specifies the superclass of an instance.
struct objc_super {
/// Specifies an instance of a class.
__unsafe_unretained _Nonnull id receiver;
/// Specifies the particular superclass of the instance to message.
#if !defined(__cplusplus) && !__OBJC2__
/* For compatibility with old objc-runtime.h header */
__unsafe_unretained _Nonnull Class class;
#else
__unsafe_unretained _Nonnull Class super_class;
#endif
/* super_class is the first class to search */
};
self.class与super.class?
当在父类的方法列表中找到之后通过objc_super
中的receiver
去调用该方法的。
objc_super -> receiver
就是此时的self
,因此最终都为self.class
,获取的都为类对象因此是一样的。
-
[self class]
方法调用的本质是 发送消息,调用class
的消息流程,拿到元类的类型,在这里是因为类已经加载到内存,所以在读取时是一个字符串类型,这个字符串类型是在map_images
的readClass
时已经加入表中 -
[super class]
打印的结果与[self class]
相同,原因是当前的super
是一个关键字,在这里只调用objc_msgSendSuper2
,其实他的消息接收者和[self class]
是一模一样的
在转成
C++
代码时显示的是objc_msgSendSuper
函数,而实际运行时是objc_msgSendSuper2
, 首个参数的类型为objc_super2
,再传递消息时,会通过第二个参数(即当前类) 的superclass
去查找方法
struct objc_super2 {
id receiver;
Class current_class;
};
ENTRY _objc_msgSendSuper2
UNWIND _objc_msgSendSuper2, NoFrame
ldp p0, p16, [x0] // p0 = real receiver, p16 = class
ldr p16, [x16, #SUPERCLASS] // p16 = class->superclass
CacheLookup NORMAL, _objc_msgSendSuper2
END_ENTRY _objc_msgSendSuper2