首先来看一个很老的题目:
如下:
@interface MyObject : NSObject @end @implementation MyObject - (id)init { self = [super init]; if (self) { NSLog(@"%@", NSStringFromClass([self class])); NSLog(@"%@", NSStringFromClass([super class])); } return self; } @end执行以下代码:
id obj = [[MyObject alloc]init];
打印信息如下:
2016-11-21 18:35:45.114 WarningDemo[63387:1224406] MyObject
2016-11-21 18:35:45.114 WarningDemo[63387:1224406] MyObject
super
是编译器标示符,并不像self
一样是一个对象,遇到向super
发的方法时会转译成objc_msgSendSuper(...)
现在我们通过源码来验证并分析一下原因:
首先我们通过clang命令输出编译器源码,这里我提取以下两行源码的编译器源码:
Class selfClass = [self class]; Class superClass = [super class];编译器源代码如下:
Class selfClass = ((Class (*)(id, SEL))(void *)objc_msgSend)((id)self, sel_registerName("class")); Class superClass = ((Class (*)(__rw_objc_super *, SEL))(void *)objc_msgSendSuper)((__rw_objc_super){(id)self, (id)class_getSuperclass(objc_getClass("MyObject"))}, sel_registerName("class"));
__rw_objc_super其实就是objc_super
/// Specifies the superclass of an instance. struct objc_super { /// Specifies an instance of a class. __unsafe_unretained 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 Class class; #else __unsafe_unretained Class super_class; #endif /* super_class is the first class to search */ };简化一下就是:
struct objc_super { id receiver; Class cls; }从编译器源码可以看到这里的receiver指向self,cls指向的是superclass,也就是NSObject。
我们来看一下objc_msgSendSuper方法的官方解释:
方法原型:
id objc_msgSendSuper(struct objc_super *super, SEL op, ...);super:一个指向
objc_super
数据结构的指针,传递消息被发送到的标识上下文的值,包含接收消息的类的实例(receiver),以及开始查找方法实现的超类(cls)
也就是说,[super class]这条语句的解释就是,依然向self发送class消息,但是消息的实现要从self的超类,这里是NSObject开始,从继承链往上查找,这里MyObject没有overwrite class这个方法,因此[self class]和[super class]一样,最终实现都是
objc_msgSend(self,sel_registerName("class"))
最终调用的都是NSObject的class方法。
你懂了吗?