OC追根溯源之Class

前兩天碰到一面試題:

//分辨下面res的是非
BOOL res1 = [[NSObject class] isKindOfClass:[NSObject class]];
BOOL res2 = [[NSObject class] isMemberOfClass:[NSObject class]];
BOOL res3 = [[Sark class] isKindOfClass:[Sark class]];
BOOL res4 = [[Sark class] isMemberOfClass:[Sark class]];

在這之前,我們先了解一下相關(guān)的定義:

Class

objc.hClass是這么定義的:

/// An opaque type that represents an Objective-C class.
typedef struct objc_class *Class;

objc_class又是啥呢?在runtime.h中能看見:

struct objc_class {
    Class isa  OBJC_ISA_AVAILABILITY;

#if !__OBJC2__
    Class super_class                                        OBJC2_UNAVAILABLE;
    const char *name                                         OBJC2_UNAVAILABLE;
    long version                                             OBJC2_UNAVAILABLE;
    long info                                                OBJC2_UNAVAILABLE;
    long instance_size                                       OBJC2_UNAVAILABLE;
    struct objc_ivar_list *ivars                             OBJC2_UNAVAILABLE;
    struct objc_method_list **methodLists                    OBJC2_UNAVAILABLE;
    struct objc_cache *cache                                 OBJC2_UNAVAILABLE;
    struct objc_protocol_list *protocols                     OBJC2_UNAVAILABLE;
#endif

} OBJC2_UNAVAILABLE;

MetaClass

上面能看到Class中有個(gè)isa參數(shù),它是指向Class元類(MetaClass)的指針。

注意到isa也是一個(gè)Class的結(jié)構(gòu)體,也就是說(shuō)MetaClass其本質(zhì)也是一個(gè)Class。

我們可以把Meta Class理解為 一個(gè)Class對(duì)象的Class。簡(jiǎn)單的說(shuō):

  • 當(dāng)我們發(fā)送一個(gè)消息給一個(gè)NSObject對(duì)象時(shí),這條消息會(huì)在對(duì)象的類的方法列表里查找
  • 當(dāng)我們發(fā)送一個(gè)消息給一個(gè)類時(shí),這條消息會(huì)在類的Meta Class的方法列表里查找

之后就有了下面的這張圖:

ocClass.jpg

能看到:

  • 每個(gè)Class都有一個(gè)isa指針指向一個(gè)唯一的MetaClass
  • 每一個(gè)MetaClassisa指針都指向最上層的MetaClass(圖中的NSObjectMetaClass
  • 最上層的MetaClassisa指針指向自己,形成一個(gè)回路
  • 每一個(gè)MetaClasssuper class指針指向它原本ClassSuper ClassMetaClass。
  • 最上層的MetaClassSuper Class指向NSObject Class本身
  • 最上層的NSObject Classsuper class指向 nil

接下來(lái)我們看看objc源碼中(源碼可到這里下載),在文件Object.mm內(nèi),上面相關(guān)方法的定義:

+ (Class)class {  
    return self;  
}
- (BOOL)isKindOf:aClass
{
    Class cls;
    for (cls = isa; cls; cls = cls->superclass)
        if (cls == (Class)aClass)
            return YES;
    return NO;
}
- (BOOL)isMemberOf:aClass
{
    return isa == (Class)aClass;
}

那么,BOOL res1 = [[NSObject class] isKindOfClass:[NSObject class]];就可以這樣對(duì)應(yīng)起來(lái)理解了:

[NSObject class]拿到的是self,類方法的return self,即上圖紫色的NSObject(Class)

根據(jù)上面- (BOOL)isKindOf:aClass的實(shí)現(xiàn),for循環(huán)首先拿到的cls = isa,也就是clsNSObject(Class)MetaClass。顯然這時(shí)候cls == (Class)aClass不成立。

隨后,cls = cls->superclass,即cls變成了NSObject(Class)MetaClasssuperclass,根據(jù)圖示可以,superclass指向的是NSObject(Class),至此cls == (Class)aClass成立,返回YES

同樣的道理,分析BOOL res3 = [[Sark class] isKindOfClass:[Sark class]];:

[Sark class]拿到的是Sark(Class),而- (BOOL)isKindOf:aClasscls拿到的值依次是Sark Meta Class->NSObject Meta Class->NSObject Class -> nil,沒(méi)有相等的,return NO

剩下兩個(gè),根據(jù)- (BOOL)isMemberOf:aClass的實(shí)現(xiàn),很容易得出結(jié)論會(huì)return NO。

喜歡我的可以關(guān)注收藏我的個(gè)人博客:Ro.bber

最后編輯于
?著作權(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)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

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

  • 轉(zhuǎn)至元數(shù)據(jù)結(jié)尾創(chuàng)建: 董瀟偉,最新修改于: 十二月 23, 2016 轉(zhuǎn)至元數(shù)據(jù)起始第一章:isa和Class一....
    40c0490e5268閱讀 2,030評(píng)論 0 9
  • 我們常常會(huì)聽說(shuō) Objective-C 是一門動(dòng)態(tài)語(yǔ)言,那么這個(gè)「動(dòng)態(tài)」表現(xiàn)在哪呢?我想最主要的表現(xiàn)就是 Obje...
    Ethan_Struggle閱讀 2,319評(píng)論 0 7
  • 一、前言 OC是一門動(dòng)態(tài)語(yǔ)言,它將很多靜態(tài)語(yǔ)言在編譯和鏈接時(shí)期做的事放到了運(yùn)行時(shí)來(lái)處理。即說(shuō)明OC需要一個(gè)編譯器和...
    雨潤(rùn)聽潮閱讀 777評(píng)論 1 0
  • 原文出處:南峰子的技術(shù)博客 Objective-C語(yǔ)言是一門動(dòng)態(tài)語(yǔ)言,它將很多靜態(tài)語(yǔ)言在編譯和鏈接時(shí)期做的事放到了...
    _燴面_閱讀 1,402評(píng)論 1 5
  • Objective-C語(yǔ)言是一門動(dòng)態(tài)語(yǔ)言,它將很多靜態(tài)語(yǔ)言在編譯和鏈接時(shí)期做的事放到了運(yùn)行時(shí)來(lái)處理。這種動(dòng)態(tài)語(yǔ)言的...
    有一種再見叫青春閱讀 668評(píng)論 0 3

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