class
1.[self class]和 [super class]
继承体系 打印结果self和super的区别:
self是类的一个隐藏参数,每个方法的实现的第一个参数即为self
super并不是隐藏参数,它实际上个只是一个"编译器标示符",它负责广高速编译器,当调用方法时,先去调用父类的方法,而不是本类中的方法
在调用[super class]的时候,runtime会去调用objc_mesSendSuper方法,而不是objc_msgSend
OBJC_EXPORT void objc_msgSendSuper(void /* struct objc_super *super, SEL op, ... */ )
/// 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 */
};
在objc_msgSendSuper方法中,第一个参数是一个objc_super的结构体,这个结构体里面有两个变量,一个是接受消息的receiver,一个是当前类的父类super_class,
objc_msgSendSuper的工作原理应该是这样的:
从objc_super结构体指向的superClass父类的方法列表开始查找selector,找到后以objc->receiver去调用父类的这个selector(注意,最后的调用者是objc->receiver,而不是super_class)
那么objc_msgSendSuper最后就转变成
// 注意这里是从父类开始msgSend,而不是从本类开始,
objc_msgSend(objc_super->receiver, @selector(class))
/// Specifies an instance of a class. 这是类的一个实例
__unsafe_unretained id receiver;
// 由于是实例调用,所以是减号方法
- (Class)class {
return object_getClass(self);
}
由于找到了父类NSObject里面的class方法的IMP,又因为传入的入参objc_super->receiver=self,self就是MJStudent,调用calss,所以父类方法的class执行IMP之后输出还是MJStudent
2.isKindOfClass与isMemberOfClass
执行结果 isKindOfClass和isMemberOfClass+ (BOOL)isKindOfClass:(Class)cls方法内部,会先去获得object_getClass的类,而object_getClass的源码实现是去调用当前类的obj->getIsa(),最后在ISA()方法中获得meta class的指针,接着在isKindOfClass中有一个循环,先判断class是否等于meta class,不等就继续循环判断是否等于super class,等于就返回YES,不等再继续取super class,,如此循环下去,循环结束返回NO
isMemberOfClass的源码实现是拿到自己的isa指针和自己比较是否相等
-(BOOL) isKindOfClass: classObj判断是否是这个类或者这个类的子类的实例
-(BOOL) isMemberOfClass: classObj 判断是否是这个类的实例