iOS 捋清楚 isKindOfClass 與 isMemberOfClass

?? 今天從源碼來徹底了解這倆方法的區(qū)別统刮。

相信很多人應該都遇到過類似的面試題,日常開發(fā)中也用這倆方法做過不少判斷魏烫,比如后臺返回的數據是不是數組怖亭,是不是null沐鼠,是不是字典挚瘟,某個實例是不是指定的控制器等等。

BOOL res1 = [[NSObject class] isKindOfClass:[NSObject class]];
        BOOL res2 = [[NSObject class] isMemberOfClass:[NSObject class]];
        BOOL res3 = [[Person class] isKindOfClass:[Person class]];
        BOOL res4 = [[Person class] isMemberOfClass:[Person class]];

        NSLog(@"%d %d %d %d", res1, res2, res3, res4);
        
        BOOL res5 = [[[NSObject new]class] isKindOfClass:[NSObject class]];
        BOOL res6 = [[[NSObject new]class] isMemberOfClass:[NSObject class]];
        BOOL res7 = [[[Person new]class] isKindOfClass:[Person class]];
        BOOL res8 = [[[Person new]class] isMemberOfClass:[Person class]];
        
        NSLog(@"%d %d %d %d", res5, res6, res7, res8);
        
        BOOL res9 = [[NSObject new] isKindOfClass:[NSObject class]];
        BOOL res10 = [[NSObject new] isMemberOfClass:[NSObject class]];
        BOOL res11 = [[Person new] isKindOfClass:[Person class]];
        BOOL res12 = [[Person new] isMemberOfClass:[Person class]];
        
        NSLog(@"%d %d %d %d", res9, res10, res11, res12);

這里面牽扯到的源碼如下:

+ (Class)class {
    return self;
}

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

+ (BOOL)isMemberOfClass:(Class)cls {
    return self->ISA() == cls;
}

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

+ (BOOL)isKindOfClass:(Class)cls {
    for (Class tcls = self->ISA(); 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;
}

先捋一下這幾個方法

  1. 類方法+ (Class)class 返回的是他自身饲梭,即類對象乘盖。
  2. 實例方法- (Class)class 返回的object_getClass(self),即實例對象的isa憔涉,對這部分有點了解的應該知道订框,實例對象的isa 指向的就是類對象。
  3. 類方法+ (BOOL)isMemberOfClass:(Class)cls兜叨,判斷的是類對象的isa(即元類)是否等于cls穿扳。
  4. 實例方法- (BOOL)isMemberOfClass:(Class)cls,判斷的是實例對象調用class方法的返回值(即如上2国旷,也就是類對象)是否與cls相等矛物。
  5. 類方法+ (BOOL)isKindOfClass:(Class)cls,這里會先取類對象的isa (self->ISA())跪但,類對象的isa指向的是元類履羞,判斷元類是否與cls相等,而且這里是一個for循環(huán),不相等的話會往元類的父類(tcls = tcls->superclass)循環(huán)去查找對比忆首。
  6. 實例方法- (BOOL)isKindOfClass:(Class)cls骨杂,這里是先取實例對象的isa ([self class]),也就是類對象,判斷類對象與cls是否相等雄卷,不相等的話會往類對象的父類(tcls = tcls->superclass)循環(huán)去查找對比搓蚪。
對實例對象,類對象丁鹉,元類不了解的可以看我前面的文章
捋清楚了上面幾個方法之后妒潭,再來看看開頭的面試題,是不是豁然開朗了揣钦。

下面我們一個個來康康雳灾。

  • BOOL res1 = [[NSObject class] isKindOfClass:[NSObject class]];
    這里可以相當于 [NSObject類對象 isKindOfClass NSObject類對象],即上述第5點冯凹,判斷的是NSObject的元類是否等于類對象谎亩,很明顯,肯定不等于宇姚,這是2個東西匈庭,接著去和元類的父類對比,那么按道理也是不相等的浑劳,但是如果對關系圖了解透徹的同學應該知道阱持,根元類的父類就是根類對象,那里這里會不太一樣魔熏,即NSObject的元類的父類等于NSObject類對象,那么最終會變成比較NSObject類對象是否等于NSObject類對象衷咽,所以這里 res1的結果為 1.

  • BOOL res2 = [[NSObject class] isMemberOfClass:[NSObject class]];
    這里可以相當于 [NSObject類對象 isMemberOfClass NSObject類對象],即上述第3點蒜绽。判斷的是NSObject的元類是否等于NSObject類對象镶骗,那必然不等于,所以這里 res2的結果為 0.

  • BOOL res3 = [[Person class] isKindOfClass:[Person class]];
    這里可以相當于 [Person類對象 isKindOfClass Person類對象]躲雅,即上述第3點鼎姊。判斷的是Person的元類是否等于類對象,必然不等于吏夯,接著去和元類的父類對比此蜈,也一樣是不等于的。這里不會向res1一樣噪生,最終也只是判斷NSObject類對象是否等于Person類對象裆赵,所以res3 結果為 0。

  • BOOL res4 = [[Person class] isMemberOfClass:[Person class]];
    這里可以相當于 [Person類對象 isMemberOfClass Person類對象]跺嗽,即上述第3點战授。判斷的是Person的元類是否等于Person類對象页藻,那必然不等于,所以這里 res2的結果為 0.

  • BOOL res5 = [[[NSObject new]class] isKindOfClass:[NSObject class]];
    這里首先調用實例對象的class方法(即上述第2點)植兰,那么就相當于 [NSObject類對象 isKindOfClass NSObject類對象]份帐,那就是res1的情況了,所以結果同 res1

  • BOOL res6 = [[[NSObject new]class] isMemberOfClass:[NSObject class]];
    那么這里一樣結果同 res2楣导。

  • BOOL res7 = [[[Person new]class] isKindOfClass:[Person class]];
    結果同 res3废境。

  • BOOL res8 = [[[Person new]class] isMemberOfClass:[Person class]];
    結果同 res4

  • BOOL res9 = [[NSObject new] isKindOfClass:[NSObject class]];
    這里相當于[NSObject實例對象 isKindOfClass NSObject類對象]筒繁,即如上述第6點噩凹,判斷的是NSObject類對象與NSObject類對象是否相等,那必然是相等的毡咏。所以res9的結果為 1驮宴。

  • BOOL res10 = [[NSObject new] isMemberOfClass:[NSObject class]];
    這里相當于[NSObject實例對象 isMemberOfClass NSObject類對象],即如上述第4點呕缭,判斷的也是NSObject類對象與NSObject類對象是否相等堵泽,那必然是相等的,所以res10的結果為 1恢总。

  • BOOL res11 = [[Person new] isKindOfClass:[Person class]];
    結果同 res9迎罗。

  • BOOL res12 = [[Person new] isMemberOfClass:[Person class]];
    結果同 res10。

最終打印結果與理論是相符的离熏。


result

end

?著作權歸作者所有,轉載或內容合作請聯系作者
  • 序言:七十年代末佳谦,一起剝皮案震驚了整個濱河市戴涝,隨后出現的幾起案子滋戳,更是在濱河造成了極大的恐慌,老刑警劉巖啥刻,帶你破解...
    沈念sama閱讀 212,884評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件奸鸯,死亡現場離奇詭異,居然都是意外死亡可帽,警方通過查閱死者的電腦和手機娄涩,發(fā)現死者居然都...
    沈念sama閱讀 90,755評論 3 385
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來映跟,“玉大人蓄拣,你說我怎么就攤上這事∨叮” “怎么了球恤?”我有些...
    開封第一講書人閱讀 158,369評論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長荸镊。 經常有香客問我咽斧,道長堪置,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,799評論 1 285
  • 正文 為了忘掉前任张惹,我火速辦了婚禮舀锨,結果婚禮上,老公的妹妹穿的比我還像新娘宛逗。我一直安慰自己坎匿,他們只是感情好,可當我...
    茶點故事閱讀 65,910評論 6 386
  • 文/花漫 我一把揭開白布雷激。 她就那樣靜靜地躺著碑诉,像睡著了一般。 火紅的嫁衣襯著肌膚如雪侥锦。 梳的紋絲不亂的頭發(fā)上进栽,一...
    開封第一講書人閱讀 50,096評論 1 291
  • 那天,我揣著相機與錄音恭垦,去河邊找鬼快毛。 笑死,一個胖子當著我的面吹牛番挺,可吹牛的內容都是我干的唠帝。 我是一名探鬼主播,決...
    沈念sama閱讀 39,159評論 3 411
  • 文/蒼蘭香墨 我猛地睜開眼玄柏,長吁一口氣:“原來是場噩夢啊……” “哼襟衰!你這毒婦竟也來了?” 一聲冷哼從身側響起粪摘,我...
    開封第一講書人閱讀 37,917評論 0 268
  • 序言:老撾萬榮一對情侶失蹤瀑晒,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后徘意,有當地人在樹林里發(fā)現了一具尸體苔悦,經...
    沈念sama閱讀 44,360評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 36,673評論 2 327
  • 正文 我和宋清朗相戀三年椎咧,在試婚紗的時候發(fā)現自己被綠了玖详。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,814評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡勤讽,死狀恐怖蟋座,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情脚牍,我是刑警寧澤向臀,帶...
    沈念sama閱讀 34,509評論 4 334
  • 正文 年R本政府宣布,位于F島的核電站莫矗,受9級特大地震影響飒硅,放射性物質發(fā)生泄漏砂缩。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 40,156評論 3 317
  • 文/蒙蒙 一三娩、第九天 我趴在偏房一處隱蔽的房頂上張望庵芭。 院中可真熱鬧,春花似錦雀监、人聲如沸双吆。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,882評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽好乐。三九已至,卻和暖如春瓦宜,著一層夾襖步出監(jiān)牢的瞬間蔚万,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,123評論 1 267
  • 我被黑心中介騙來泰國打工临庇, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留反璃,地道東北人。 一個月前我還...
    沈念sama閱讀 46,641評論 2 362
  • 正文 我出身青樓假夺,卻偏偏與公主長得像淮蜈,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子已卷,可洞房花燭夜當晚...
    茶點故事閱讀 43,728評論 2 351