美文网首页
『ios』我知道[self class] [super cla

『ios』我知道[self class] [super cla

作者: butterflyer | 来源:发表于2021-07-08 19:19 被阅读0次

有这么一种情况student继承person,那么问题来了。

//student类中
- (instancetype)init
{
    if (self = [super init]) {
        NSLog(@"[self class] = %@", [self class]); 
        NSLog(@"[self superclass] = %@", [self superclass]);
        NSLog(@"--------------------------------");
        NSLog(@"[super class] = %@", [super class]); 
        NSLog(@"[super superclass] = %@", [super superclass]); 
    }
    return self;
}

上面这种情况的答案是什么?以及为什么是这样的。
首先对于 [self class] 和 [self superclass] 这个很好理解,一个是 student 一个是person
那下面两行的答案呢?
可能你认为会是 person 和 nsobject。
但这是不正确的。
首先对于前两行的打印,来看一下源码

//[self class]
 ((Class (*)(id, SEL))(void *)objc_msgSend)((id)self, sel_registerName("class")));
//[self superclass]
 ((Class (*)(id, SEL))(void *)objc_msgSend)((id)self, sel_registerName("superclass")));

都是通过objc_msgSend来发送消息。

来看一下后面两行的源码

//[super class]
 ((Class (*)(__rw_objc_super *, SEL))(void *)objc_msgSendSuper)((__rw_objc_super){(id)self, (id)class_getSuperclass(objc_getClass("MJStudent"))}, sel_registerName("class")));

//[super superclass]
 ((Class (*)(__rw_objc_super *, SEL))(void *)objc_msgSendSuper)((__rw_objc_super){(id)self, (id)class_getSuperclass(objc_getClass("MJStudent"))}, sel_registerName("superclass")));

请注意这个结构体__rw_objc_super.

struct __rw_objc_super { 
    struct objc_object *object; 
    struct objc_object *superClass; 
};

objc_msgSendSuper传进两个参数,一个是__rw_objc_super的结构体,一个是Selector方法。
那么我们可以找一下objc_msgSendSuper的方法实现,很可惜是汇编实现的。
在源码中找到了对于objc_msgSendSuper的注释。

/** 
 * Sends a message with a simple return value to the superclass of an instance of a class.
 * 
 * @param super A pointer to an \c objc_super data structure. Pass values identifying the
 *  context the message was sent to, including the instance of the class that is to receive the
 *  message and the superclass at which to start searching for the method implementation.
 * @param op A pointer of type SEL. Pass the selector of the method that will handle the message.
 * @param ...
 *   A variable argument list containing the arguments to the method.
 * 
 * @return The return value of the method identified by \e op.
 * 
 * @see objc_msgSend
 */
OBJC_EXPORT id _Nullable
objc_msgSendSuper(struct objc_super * _Nonnull super, SEL _Nonnull op, ...)
    OBJC_AVAILABLE(10.0, 2.0, 9.0, 1.0, 2.0);

请注意看上面对于objc_super的解释,including the instance of the class that is to receive the

  • message and the superclass at which to start searching for the method implementation 翻译 包含了一个实例类用来接收消息,另一个superclass是开始搜索方法的地方。
    那我们回过头来再来看[super class]的源码。
 ((Class (*)(__rw_objc_super *, SEL))(void *)objc_msgSendSuper)((__rw_objc_super){(id)self, (id)class_getSuperclass(objc_getClass("MJStudent"))}, sel_registerName("class")));

结构体第一个参数self是消息接受者
第二个参数是开始搜索class方法的地方,也就是从student的父类person开始搜索那个class方法。记不记得之前很经典的那张类图,由于person没有实现class方法,所以继续向上寻找,一直找到nsobjct,然后找到了,所以[super class]返回的是student ,[super superclass]的结果是person。

(__rw_objc_super){
(id)self, 
(id)class_getSuperclass(objc_getClass("MJStudent"))
}

对于class和superClass的底层源码实现如下.

- (Class)class
{
    return object_getClass(self);
}

- (Class)superclass
{
    return class_getSuperclass(object_getClass(self));
}
image.png

相关文章

网友评论

      本文标题:『ios』我知道[self class] [super cla

      本文链接:https://www.haomeiwen.com/subject/mxptpltx.html