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

2021-07-08  本文已影响0人  butterflyer

有这么一种情况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

 ((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
上一篇 下一篇

猜你喜欢

热点阅读