class

2021-03-11  本文已影响0人  牛奶红茶

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 判断是否是这个类的实例

上一篇下一篇

猜你喜欢

热点阅读