小碼哥底層原理筆記:Runtime之super指針

我們先創(chuàng)建兩個類Person和Student,Student繼承自Person類,接下來我們在Student打印如下代碼:

@implementation Student

- (void)run{
    [super run];
    NSLog(@"Student");
}

- (instancetype)init{
    if (self = [super init]) {
        NSLog(@"[self class] = %@",[self class]);//Student
        NSLog(@"[self superclass] = %@",[self superclass]);//Person
        NSLog(@"----------------------");
        NSLog(@"[super class] = %@",[super class]);//Student
        NSLog(@"[super superclass] = %@",[super superclass]);//Person
    }
    return self;
}

@end

發(fā)現(xiàn)super跟self好像效果都是一樣的。這是什么原因,那我們就需要去看看super方法的底層調(diào)用了。我們看下run方法底層是怎樣的?

- (void)run{
    [super run];
    NSLog(@"Student");
}
struct __rw_objc_super arg = {
    (id)self,//消息接收者
    (id)class_getSuperclass(objc_getClass("Student"))//消息接收者的父類
    };
    
    objc_msgSendSuper(arg,
                      @selector(run));

可以看到super是通過objc_msgSendSuper發(fā)送消息,其中arg中消息接收者還是self。傳進去的那個父類是表示直接從父類去查找方法,而不是跟往常一樣從當前對象查找。那么[super class]就是直接從父類Person去搜索,而class方法在NSObject里面,class的底層實現(xiàn)是這樣

- (Class)class{
 return object_getClass(self);
}

class調(diào)用返回值取決于方法接收者self跟父類無關,所以打印的還是Student。

superClass的底層實現(xiàn)是這樣:

+ (id)superclass
{ 
    return self->superclass; 
}

- (id)superclass
{ 
    return isa->superclass; 
}

其實返回的就是消息接收者的父類

總結(jié):super的本質(zhì)是:(1)消息接收者還是當前對象,并不是父類。(2)super方法調(diào)用時是直接從父類去查找方法,而不是從當前對象開始查找

isMemberOfClass和isKindOfClass區(qū)別

- (BOOL)isMemberOfClass:(Class)cls {
    return [self class] == cls;
}

- (BOOL)isKindOfClass:(Class)cls {
    for (Class tcls = [self class]; tcls; tcls = tcls->superclass) {
        if (tcls == cls) return YES;
    }
    return NO;
}

很明顯isMemberOfClass是判斷當前對象是否是這個類對象。

isKindOfClass稍微復雜一點,首先是拿當前對象的類對象去比較看是否相等,如果不相等就跟父類比,直到NSObject基類。

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

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

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