面试之---[self class] 和 [super cla
2020-04-14 本文已影响0人
开了那么
实例演示
1、
@interface CCStudent : Person
@end
@implementation CCStudent
-(instancetype)init{
if (self = [super init]) {
NSLog(@"self class --- %@",[self class]);
NSLog(@"super class --- %@",[super class]);
NSLog(@"self superclass --- %@",[self superclass]);
NSLog(@"super superclass ---%@",[super superclass]);
}
return self;
}
@end
---------------------------------------------
self class --- CCStudent
super class --- CCStudent
self superclass --- Person
super superclass ---Person
转译成C++代码
static instancetype _I_CCStudent_init(CCStudent * self, SEL _cmd) {
if (self = ((CCStudent *(*)(__rw_objc_super *, SEL))(void *)objc_msgSendSuper)((__rw_objc_super){(id)self, (id)class_getSuperclass(objc_getClass("CCStudent"))}, sel_registerName("init"))) {
NSLog((NSString *)&__NSConstantStringImpl__var_folders_8v_w12n8yrs075g6wv21qzg72180000gn_T_CCStudent_321efc_mi_0,((Class (*)(id, SEL))(void *)objc_msgSend)((id)self, sel_registerName("class")));
NSLog((NSString *)&__NSConstantStringImpl__var_folders_8v_w12n8yrs075g6wv21qzg72180000gn_T_CCStudent_321efc_mi_1,((Class (*)(__rw_objc_super *, SEL))(void *)objc_msgSendSuper)((__rw_objc_super){(id)self, (id)class_getSuperclass(objc_getClass("CCStudent"))}, sel_registerName("class")));
NSLog((NSString *)&__NSConstantStringImpl__var_folders_8v_w12n8yrs075g6wv21qzg72180000gn_T_CCStudent_321efc_mi_2,((Class (*)(id, SEL))(void *)objc_msgSend)((id)self, sel_registerName("superclass")));
NSLog((NSString *)&__NSConstantStringImpl__var_folders_8v_w12n8yrs075g6wv21qzg72180000gn_T_CCStudent_321efc_mi_3,((Class (*)(__rw_objc_super *, SEL))(void *)objc_msgSendSuper)((__rw_objc_super){(id)self, (id)class_getSuperclass(objc_getClass("CCStudent"))}, sel_registerName("superclass")));
}
return self;
}
---------------------------------------------------------
简化代码如下
// NSLog(
objc_msgSend)(
self,
sel_registerName("class")));
)
// NSLog(
objc_msgSendSuper)(
{
self,
class_getSuperclass(objc_getClass("CCStudent"))
}
sel_registerName("class")));
)
// NSLog(
objc_msgSend)(
self,
sel_registerName("superclass")));
)
// NSLog(
objc_msgSendSuper)(
{
self,
class_getSuperclass(objc_getClass("CCStudent"))
}
sel_registerName("superclass")));
)
下面我们通过源码来分析一下
objc_super 定义
struct objc_super {
/// Specifies an instance of a class.
__unsafe_unretained _Nonnull id receiver;//消息接收者
__unsafe_unretained _Nonnull Class super_class;//消息接收者父类
};
objc_msgSendSuper 定义
方法包含两个参数,一个接收者是一个实例对象: the instance of the class
另外一个是方法
其中需要注意的是这句:
message and the superclass at which to start searching for the method implementation.
翻译为:传入父类 是指从父类开始搜索
/**
* 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);
从而我们可以理解:下面这句代码
NSLog(@"super class --- %@",[super class]);
我们传入super,表示是从父类(Person)中开始搜索方法,但是我们知道其实class 方法是在NSObject中实现的,无论是父类还是子类调用方法,都要去NSObject中调用方法。
通过看源码我们可以知道class 方法的实现,它是返回当前对象的返回值,class 返回值取决于 self,即receiver(消息接收者)
+ (Class)class {
return self;
}
- (Class)class {
return object_getClass(self);
}
+ (Class)superclass {
return self->superclass;
}
- (Class)superclass {
return [self class]->superclass;
// return object_getClass(self) ->superclass;;
}
所以我们可以看出,下面代码
NSLog(@"super class --- %@",[super class]);
转译成c++代码后
// NSLog(
objc_msgSendSuper)(
{
self,
class_getSuperclass(objc_getClass("CCStudent"))
}
sel_registerName("class")));
)
消息接收者仍然为self
总结:
[super message]的底层实现
1、消息的接收者仍然为子类对象
2、从父类开始查找方法的实现