一起看源碼-isKindOfClass 和isMemberOfClass的區(qū)別

相關(guān)鏈接:objc4-750配置下載教程
日常開(kāi)發(fā)中,我們想必會(huì)經(jīng)常通過(guò)isKindOfClass和isMemberOfClass去處理一些邏輯判斷,但是我們真的了解它們嗎?
話不多說(shuō)我們直接上場(chǎng)景:

@interface Person : NSObject
@end
@implementation Person
@end

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        BOOL re1 = [(id)[NSObject class] isKindOfClass:[NSObject class]];
        BOOL re2 = [(id)[NSObject class] isMemberOfClass:[NSObject class]];

        BOOL re3 = [(id)[Person class] isKindOfClass:[Person class]];
        BOOL re4 = [(id)[Person class] isMemberOfClass:[Person class]];
        NSLog(@" re1 :%hhd re2 :%hhd re3 :%hhd re4 :%hhd ",re1,re2,re3,re4);
    }
    return 0;
}

輸出結(jié)果:

2019-08-21 17:01:00.054439+0800 001-isKindOfClass&isMemberOfClass[25960:1615638]  re1 :1 re2 :0 re3 :0 re4 :0

接下來(lái)我們通過(guò)objc源碼來(lái)分析為什么會(huì)是輸出這個(gè)樣的一個(gè)結(jié)果~

+ (BOOL)isMemberOfClass:(Class)cls {
    return object_getClass((id)self) == cls;
}

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

+ (BOOL)isKindOfClass:(Class)cls {
    for (Class tcls = object_getClass((id)self); tcls; tcls = tcls->superclass) {
        if (tcls == cls) return YES;
    }
    return NO;
}

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

由源碼得知:

在isKindOfClass中有一個(gè)循環(huán),先判斷當(dāng)前類是否等于元類,不等就繼續(xù)循環(huán)取元類的父類進(jìn)行判斷,不等再繼續(xù)取父類,如此循環(huán)下去。

然而此時(shí)我們需要上isa走向圖:


[NSObject class] 調(diào)用 isKindOfClass,第一次判斷先判斷NSObject 和 NSObject的元類是否相等,從圖上我們也可以看出,NSObject的元類是根元類。接著第二次循環(huán)判斷NSObject與根元類的父類是否相等。還是從那張圖上面我們可以看到:根元類 的父類也就是NSObject本身。所以第二次循環(huán)相等,于是第一行res1輸出應(yīng)該為YES。

[Person class] 調(diào)用 isKindOfClass,第一次for循環(huán),Person的元類與[Person class]不等,第二次for循環(huán),Person元類的父類 指向的是 NSObject Meta Class(根元類), 和[Person class]不相等。第三次for循環(huán),根元類指向的是NSObject,和 [Person Class] 不相等。第四次循環(huán),NSObject Class 的父類 指向 nil, 和 Person Class不相等。第四次循環(huán)之后,退出循環(huán),所以第三行的res3輸出為NO。

isMemberOfClass的源碼實(shí)現(xiàn)是拿到自己的isa指針和自己比較,是否相等。

第二行 isa 指向 NSObject 的 元類,所以和 NSObject不相等。第四行,isa指向Person的元類,和Perosn Class也不等,所以第二行res2和第四行res4都輸出NO。

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

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

  • 轉(zhuǎn)載自https://mp.weixin.qq.com/s/B4Z-7YQ8CMhZ0kCrxe3XAg 欲誠(chéng)其意...
    碧玉小瑕閱讀 648評(píng)論 1 1
  • 這些知識(shí)老生常談了,我也寫過(guò)相關(guān)博客??墒歉杏X(jué)還是不咋地。今天從頭來(lái)過(guò),弄個(gè)專題分模塊專門仔細(xì)研究下。 NSObj...
    充滿活力的早晨閱讀 401評(píng)論 2 3
  • 下面代碼輸出什么? self super @implementation Son : Father - (id)i...
    cmhfx1閱讀 463評(píng)論 0 0
  • 參考文章 清晰理解Objective-C元類object_getClass(obj)與[obj class]的區(qū)別...
    黑化肥發(fā)灰閱讀 1,086評(píng)論 0 51
  • runtime 運(yùn)行時(shí)語(yǔ)言,實(shí)現(xiàn)Object-C的C語(yǔ)言庫(kù),將OC轉(zhuǎn)換成C進(jìn)行編譯的過(guò)渡者。 作為一門動(dòng)態(tài)編程語(yǔ)言...
    夜雨聲煩_閱讀 627評(píng)論 0 0

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