[self class] 和 [super class]

问题抛出

[self class][super class]结果是否一样呢

- (instancetype)init{
    self = [super init];
    if (self) {
        NSLog(@"%@",NSStringFromClass([self class]));
        NSLog(@"%@",NSStringFromClass([super class]));
//打印结果都为`Student`
    }
}
[self class]

class方法是什么

- (Class)class {
    return object_getClass(self);
}
///
Class object_getClass(id obj)
{
    if (obj) return obj->getIsa();
    else return Nil;
}

最终渠道的objisa.
首先来看[self class]因为这里objstudent对象,所以这里打印Student为当前类.

[super class]
方法1 汇编

前边[self class],调用 class方法的为 self对象,那么super是个什么呢?
我们不妨 Debug Workflow -> always show disassembly看汇编.
方法的调用说白了就是消息的发送过程.那么汇编有没有类似objc_mesSend呢,发现[super class]其实是调用了objc_msgSendSuper

OBJC_EXPORT void
objc_msgSendSuper(void /* struct objc_super *super, SEL op, ... */ )
    OBJC_AVAILABLE(10.0, 2.0, 9.0, 1.0, 2.0);

第一个参数为一个objc_super的结构体

struct objc_super {
    __unsafe_unretained _Nonnull id receiver;
    __unsafe_unretained _Nonnull Class super_class;
};

那么[super class]就等价于

struct objc_super lg_super = {
//我们这里研究对象为当前对象所以消息接收这位self
   self,
   class_getSuperclass([self class]),
};
objc_msgSendSuper(&lg_super,@selector(class))

打印结果依然为Student

方法2 hook
@implementation NSObject (JS)

+ (void)load{
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
         [JSRuntimeTool js_bestMethodSwizzlingWithClass:self oriSEL:@selector(class) swizzledSEL:@selector(js_class)];
    });
}

- (Class)js_class{
    NSLog(@"来了,老弟");
//注意这里会打印两次,因为方法交换,return 还调用了一次
    return [self lg_class]; // sel -> imp(class)
}
@end
[self class] 和 [super class] 区别
  • [super class] 速度更快
    [self class]是正常的消息发送流程objc_msgSend,
    方法的查找流程,先找自己->父类->......的一个递归流程
    那么objc_msgSendSuper,跳过自己的查找流程,直接去父类里找,速度更快
    还有一种比[super class]速度更快的[NSObject class]直接找根类
总结
  • [self class] 就是发送消息objc_msgSend,消息接受者是 self 方法编号:class

  • [super class] 本质就是objc_msgSendSuper, 消息的接受者还是 self 方法编号:class 只是objc_msgSendSuper 会更快 直接跳过 self 的查找

你可能感兴趣的:([self class] 和 [super class])