先给一个面试题:
打印结果如下:
答案是否与预期的设想一样呢?
1.官方如何解释super关键字的?
super的官方解释如下:
从官方解释,可以明确了解到当我们使用“super”关键字发送消息的时候,编译器会转化为调用objc_msgSendSuper这个方法来发送消息。
查看runtime的源码,了解objc_msgSendSuper的定义如下:
objc_msgSendSuper(struct objc_super * _Nonnull super, SEL _Nonnull op, ...)
查看objc_msgSendSuper的解释如下:‘
定义可知objc_msgSendSuper需要传入objc_super结构体类型的指针 和方法名以及参数。objc_super包含了实例对象(作为消息的接收者)和父类(父类是对象方法开始查找的对象)。查看源码,可知objc_super的结构体定义如下:
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 */
};
定义中,有一句话“super_class is the first class to search”,这句话的意思是说:super_class这个参数是第一个查找方法的类。一般查找方法是先从自己的类查找,没有找到再从父类去查找,一直往上,直到查找到NSObject为止,如果用了super后,是先从父类开始查找。
综上所诉,我们可以得出,当我们调用super的时候,程序会从父类开始查找方法,找到了就调用父类的方法,把方法返回,而方法的接收者是receiver(receiver是根据谁调用了这个了方法来判断的)。
2.为什么[super class] 不是Person,而是Student呢?
从上面的解析中,我们可以知道当调用[super class]编译器就会转成:
objc_megSendSuper((objc_super){self, [Person class ]}, @seletor(class))
也就是说会调用父类的class,而class的底层实现如下:
- (Class)class {
return object_getClass(self);
}
object_getClass(self)是谁呢?就是消息的接收者,消息的接收者又是student,所以,打印出来的就是student。
有个参考的链接说的更清楚:https://www.jianshu.com/p/87fe5efe104e