[self class] 和 [super class]

問題拋出

[self class][super class]結(jié)果是否一樣呢

- (instancetype)init{
    self = [super init];
    if (self) {
        NSLog(@"%@",NSStringFromClass([self class]));
        NSLog(@"%@",NSStringFromClass([super class]));
//打印結(jié)果都為`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為當(dāng)前類.

[super class]
方法1 匯編

前邊[self class],調(diào)用 class方法的為 self對象,那么super是個什么呢?
我們不妨 Debug Workflow -> always show disassembly看匯編.
方法的調(diào)用說白了就是消息的發(fā)送過程.那么匯編有沒有類似objc_mesSend呢,發(fā)現(xiàn)[super class]其實是調(diào)用了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);

第一個參數(shù)為一個objc_super的結(jié)構(gòu)體

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

那么[super class]就等價于

struct objc_super lg_super = {
//我們這里研究對象為當(dāng)前對象所以消息接收這位self
   self,
   class_getSuperclass([self class]),
};
objc_msgSendSuper(&lg_super,@selector(class))

打印結(jié)果依然為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 還調(diào)用了一次
    return [self lg_class]; // sel -> imp(class)
}
@end
[self class] 和 [super class] 區(qū)別
  • [super class] 速度更快
    [self class]是正常的消息發(fā)送流程objc_msgSend,
    方法的查找流程,先找自己->父類->......的一個遞歸流程
    那么objc_msgSendSuper,跳過自己的查找流程,直接去父類里找,速度更快
    還有一種比[super class]速度更快的[NSObject class]直接找根類
總結(jié)
  • [self class] 就是發(fā)送消息objc_msgSend,消息接受者是 self 方法編號:class

  • [super class] 本質(zhì)就是objc_msgSendSuper, 消息的接受者還是 self 方法編號:class 只是objc_msgSendSuper 會更快 直接跳過 self 的查找

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容