源码分析iOS中的super

首先来看一个很老的题目:

如下:

@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


有人解释说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方法。

你懂了吗?



猜你喜欢

转载自blog.csdn.net/junjun150013652/article/details/53262226