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)體,也就是說MetaClass其本質(zhì)也是一個(gè)Class逊脯。

我們可以把Meta Class理解為 一個(gè)Class對象的Class优质。簡單的說:

  • 當(dāng)我們發(fā)送一個(gè)消息給一個(gè)NSObject對象時(shí),這條消息會在對象的類的方法列表里查找
  • 當(dāng)我們發(fā)送一個(gè)消息給一個(gè)類時(shí),這條消息會在類的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

接下來我們看看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]];就可以這樣對應(yīng)起來理解了:

[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,沒有相等的,return NO组砚。

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

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

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末艾帐,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子改化,更是在濱河造成了極大的恐慌掩蛤,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,839評論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件陈肛,死亡現(xiàn)場離奇詭異,居然都是意外死亡兄裂,警方通過查閱死者的電腦和手機(jī)句旱,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,543評論 2 382
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來晰奖,“玉大人谈撒,你說我怎么就攤上這事∝夷希” “怎么了啃匿?”我有些...
    開封第一講書人閱讀 153,116評論 0 344
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我溯乒,道長夹厌,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,371評論 1 279
  • 正文 為了忘掉前任裆悄,我火速辦了婚禮矛纹,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘光稼。我一直安慰自己或南,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,384評論 5 374
  • 文/花漫 我一把揭開白布艾君。 她就那樣靜靜地躺著采够,像睡著了一般。 火紅的嫁衣襯著肌膚如雪冰垄。 梳的紋絲不亂的頭發(fā)上蹬癌,一...
    開封第一講書人閱讀 49,111評論 1 285
  • 那天,我揣著相機(jī)與錄音播演,去河邊找鬼冀瓦。 笑死,一個(gè)胖子當(dāng)著我的面吹牛写烤,可吹牛的內(nèi)容都是我干的翼闽。 我是一名探鬼主播,決...
    沈念sama閱讀 38,416評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼洲炊,長吁一口氣:“原來是場噩夢啊……” “哼感局!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起暂衡,我...
    開封第一講書人閱讀 37,053評論 0 259
  • 序言:老撾萬榮一對情侶失蹤询微,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后狂巢,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體撑毛,經(jīng)...
    沈念sama閱讀 43,558評論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,007評論 2 325
  • 正文 我和宋清朗相戀三年唧领,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了藻雌。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,117評論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡斩个,死狀恐怖胯杭,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情受啥,我是刑警寧澤做个,帶...
    沈念sama閱讀 33,756評論 4 324
  • 正文 年R本政府宣布鸽心,位于F島的核電站,受9級特大地震影響居暖,放射性物質(zhì)發(fā)生泄漏顽频。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,324評論 3 307
  • 文/蒙蒙 一膝但、第九天 我趴在偏房一處隱蔽的房頂上張望冲九。 院中可真熱鬧,春花似錦跟束、人聲如沸莺奸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,315評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽灭贷。三九已至,卻和暖如春略贮,著一層夾襖步出監(jiān)牢的瞬間甚疟,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,539評論 1 262
  • 我被黑心中介騙來泰國打工逃延, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留览妖,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 45,578評論 2 355
  • 正文 我出身青樓揽祥,卻偏偏與公主長得像讽膏,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子拄丰,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,877評論 2 345

推薦閱讀更多精彩內(nèi)容

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