有这么一种情况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
网友评论