為了方便講解饵撑,以下列出isMemberOfClass和isKindOfClass的實(shí)例方法和類方法底層實(shí)現(xiàn)
由上圖可知:
isMemberOfClass:
此處YYPerson繼承至NSObject
分析:
實(shí)例方法:因?yàn)橹皇呛?jiǎn)單的判斷方法調(diào)用者的類對(duì)象是否等于傳入的cls墩衙,所以[p1 isMemberOfClass:[NSObject class]] 為0凫碌,[p1 isMemberOfClass:[YYPerson class]]為1
類方法:是通過(guò)判斷object_getClass((id) self ) == cls邻吭,我們可知類方法中的self是類對(duì)象格嗅,所以是判斷元對(duì)象是否等于cls,很顯然YYPerson元對(duì)象不是NSObject類對(duì)象捏雌,也不等于YYPerson類對(duì)象跃赚,所以[YYPerson isMemberOfClass:[NSObject class]]為0,[YYPerson isMemberOfClass:[YYPerson class]]為0性湿。
補(bǔ)充:
object_getClass(id obj):此方法如果傳入的是instance對(duì)象纬傲,返回class對(duì)象。如果是class對(duì)象肤频,返回mate-class對(duì)象叹括。如果是meta-class對(duì)象,返回NSObject的meta-class對(duì)象
objc_getClass(const char *) :傳入字符串類名宵荒,返回對(duì)應(yīng)類對(duì)象
-(Class)class; + (Class) class; :?返回的是類對(duì)象
isKindOfClass:
分析:
實(shí)例方法:實(shí)例方法中[self class],返回類對(duì)象汁雷,即tcls為類對(duì)象,首先會(huì)判斷tcls是否等于cls,如果不等于將繼續(xù)遍歷报咳,tcls supperClass指針繼續(xù)往上查找侠讯。
[p1 isKindOfClass:[NSObject class]]:
因?yàn)閠cls 為p1類對(duì)象,因?yàn)椴坏扔赱NSObject class],所以繼續(xù)遍歷(supperClass指針指向可以查看OC對(duì)象內(nèi)存布局這一節(jié))暑刃,找到[NSObject class]厢漩,此時(shí)相等所以打印1;
[p1 isKindOfClass:[YYPerson class]]:
因?yàn)閠cls 為p1類對(duì)象岩臣,等于[YYPerson class]所以打印1溜嗜;
類方法:類方法中object_getClass((id) self ),返回meta對(duì)象,即tcls為meta對(duì)象架谎,首先會(huì)判斷tcls是否等于cls,如果不等于將繼續(xù)遍歷炸宵,tcls supperClass指針繼續(xù)往上查找。
[YYPerson isKindOfClass:[NSObject class]]:
因?yàn)閠cls 為p1元對(duì)象狐树,因?yàn)椴坏扔赱NSObject class],所以繼續(xù)遍歷(supperClass指針指向可以查看OC對(duì)象內(nèi)存布局這一節(jié))焙压,找到NSObject 元對(duì)象,此時(shí)仍然不相等抑钟,所以繼續(xù)遍歷涯曲,由于Root ?Class(meta)的supperClass指針指向,Root Class(class),(可查看OC對(duì)象內(nèi)存布局指針指向圖在塔,或者注意點(diǎn)說(shuō)明) 所以NSObject 元對(duì)象的supperClass 最終指向NSObject類對(duì)象幻件,所以相等,打印1
[YYPerson isKindOfClass:[YYPerson class]]:
因?yàn)閠cls 為p1元對(duì)象蛔溃,因?yàn)椴坏扔赮YPerson 類對(duì)象绰沥,所以繼續(xù)遍歷找到NSObject 元對(duì)象篱蝇,此時(shí)仍然不相等,所以繼續(xù)遍歷徽曲,找到NSObject類對(duì)象仍然不相等零截,繼續(xù)遍歷,因?yàn)镹SObject的類對(duì)象supperClass指針為nil,所以不相等秃臣,打印0涧衙;
總結(jié):
isKindOfClass和isMemberOfClass:
兩者都能檢測(cè)一個(gè)對(duì)象是否是某個(gè)類的成員, 兩者之間的區(qū)別是:isKindOfClass不但可以用來(lái)確定一個(gè)對(duì)象是否是一個(gè)類的成員奥此,也可以用來(lái)確定一個(gè)對(duì)象是否是派生自該類的類的成員 弧哎,而isMemberOfClass做不到后一點(diǎn)。
實(shí)例方法都是判斷對(duì)象的類對(duì)象是否==傳入?yún)?shù)稚虎,類方式都是判斷元對(duì)象是否== 傳入?yún)?shù)撤嫩。
但是isKindOfClass當(dāng)判斷不等于時(shí),還會(huì)去查找superClass指針指向的對(duì)象是否等于傳入?yún)?shù)蠢终。而isMemberOfClass不會(huì)序攘。因此isKindOfClass可以確定一個(gè)對(duì)象是否是一個(gè)類的成員,也可以用來(lái)確定一個(gè)對(duì)象是否是派生自該類的類的成員蜕径。