首先来看一个很老的题目:
如下:
@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
这里我们贴出class方法的官方文档
Instance Method
class
Returns the class object for the receiver’s class.
就是说class返回的是消息接受者的类,注意是消息接受者,继续分析
有人解释说objc中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
我们来看看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方法。
你懂了吗?