iOS 對(duì)實(shí)例缸浦、類對(duì)象、元類氮兵、根元類驗(yàn)證

精華Pod庫分享

一裂逐、類、根類泣栈、元類卜高、根元類關(guān)系圖

網(wǎng)上流傳一張類,元類南片,根元類的關(guān)系圖掺涛。詳細(xì)描述了它們相互間的繼承關(guān)系和isa指向關(guān)系。下面用代碼對(duì)這張圖進(jìn)行驗(yàn)證疼进。


屏幕快照 2019-08-14 下午4.46.13.png

二薪缆、驗(yàn)證關(guān)系

驗(yàn)證之前我們了解一下兩個(gè)runtime函數(shù)

  • class_getSuperclass()
    • 通過object_getClass獲取對(duì)象isa指針指向鏈。
      object_getClass參數(shù)是id類型伞广,它返回的是這個(gè)id的isa指針?biāo)赶虻腃lass拣帽,如果傳參是Class,則返回該Class的metaClass嚼锄。
  • object_getClass()
    • 通過class_getSuperclass方法獲取對(duì)象的繼承鏈减拭。
      class_getSuperclass 參數(shù)是Class類型,它返回的是該Class的superClass指針指向的Class区丑。

Person 類繼承自NSObject

 Person *p           = [Person new];
    Class  class1       = object_getClass(p); // 獲取p ---> 類對(duì)象
    Class  class2       = [p class];  // 獲取p ---> 類對(duì)象
    NSLog(@"class1 === %p class1Name == %@ class2 === %p class2Name == %@",class1,class1,class2,class2);
    
    /** 元類查找過程 */
    Class  class3       = objc_getMetaClass(object_getClassName(p)); // 獲取p ---> 元類
    NSLog(@"class3 == %p class3Name == %@",class3,class3);
    
    Class  class4       = objc_getMetaClass(object_getClassName(class3)); // 獲取class3 ---> 元類  此時(shí)的元類拧粪,class4就是根元類修陡。
    NSLog(@"class4 == %p class4Name == %@",class4,class4); // class4 == 0x106defe78 class4Name == NSObject
    
    
    /** 元類查找結(jié)束,至此可霎。我們都知道 根元類 的superClass指針是指向 根類對(duì)象 的魄鸦;根類對(duì)象的isa指針有指向根元類對(duì)象;根元類對(duì)象的isa指針指向根元類自己癣朗;根類對(duì)象的superClass指針指向nil */
    Class  class5       = class_getSuperclass(class1);  // 獲取 類對(duì)象的父類對(duì)象
    NSLog(@"class5 == %p class5Name == %@",class5,class5);  //class5 == 0x106defec8 class5Name == NSObject

    // 此時(shí)返現(xiàn)class5 已經(jīng)是NSObject号杏,我們?cè)俅潍@取class5的父類,驗(yàn)證class5是否是 根類對(duì)象
    Class  class6       = class_getSuperclass(class5);  // 獲取 class5的父類對(duì)象
    NSLog(@"class6 == %p class6Name == %@",class6,class6); // class6 == 0x0 class6Name == (null) 至此根類對(duì)象驗(yàn)證完畢斯棒。
    
    
    /** 驗(yàn)證根類對(duì)象與根元類對(duì)象的關(guān)系 */
    Class  class7       = objc_getMetaClass(object_getClassName(class5)); // 獲取根類對(duì)象 對(duì)應(yīng)的  根元類 是否是class4 對(duì)應(yīng)的指針地址
    NSLog(@"class7 == %p class7Name == %@",class7,class7);  // class7 == 0x106defe78 class7Name == NSObject
    
    Class  class8      =  class_getSuperclass(class4);  // 獲取根元類class4  superClass 指針的指向 是否是根類對(duì)象class5 的指針地址
    NSLog(@"class8 == %p class8Name == %@",class8,class8);  // class8 == 0x106defec8 class8Name == NSObject; class8與class5指針地址相同
    
    Class  class9       = objc_getMetaClass(object_getClassName(class4)); // 獲取根元類 isa 指針是否是指向自己
    NSLog(@"class9 == %p class9Name == %@",class9,class9);  //  class9 == 0x106defe78 class9Name == NSObject主经; class9 與 class4荣暮、class7指針地址相同

結(jié)果

由上運(yùn)行結(jié)果可知:


屏幕快照 2019-08-15 下午1.56.59.png
  • 實(shí)例對(duì)象:p
  • 類對(duì)象 :class1、class2
  • 元類對(duì)象:class3
  • 根元類 : class4罩驻、class7穗酥、calss9
  • 根類對(duì)象:class5、calss8

總結(jié)圖

屏幕快照 2019-08-15 下午2.56.02.png

三惠遏、iOS中的 isKindOfClass 和 isMemberOfClass區(qū)別砾跃?

逆向?qū)崿F(xiàn)

  • 如下,Person繼承自NSObject节吮,[Person class]的地址抽高,就是Person實(shí)例的類對(duì)象地址。
 Person *son = [Person new];
    Class class1 = object_getClass(son);
    NSLog(@"%p  ===   %p   ====   %p  ==== %p",class1,[son class],[Person class],son);
打印結(jié)果:
2019-09-20 15:24:50.777969+0800 sortTime[3041:228435] 
0x105248970  ===   0x105248970   ====   0x105248970  ==== 0x600001628930
  • 列子
    BOOL res1 = [(id)[NSObject class] isKindOfClass:[NSObject class]];
    BOOL res2 = [(id)[NSObject class] isMemberOfClass:[NSObject class]];
    BOOL res3 = [(id)[Sark class] isKindOfClass:[Sark class]];
    BOOL res4 = [(id)[Sark class] isMemberOfClass:[Sark class]];
    BOOL res5 = [(id)[Sark class] isKindOfClass:[NSObject class]];
    BOOL res6 = [(id)[Sark class] isMemberOfClass:[NSObject class]];

打印結(jié)果:
2019-09-20 15:10:22.235225+0800 sortTime[2852:215634] 1 0 0 0 1 0
  • 驗(yàn)證 [(id)[NSObject class] isKindOfClass:[NSObject class]]返回YES
    詳解
    • isKindOfClass內(nèi)部實(shí)現(xiàn)
 //逆向反編譯得到的源碼
- (BOOL) isKindOfClassITX:(Class)class
{
    NSLog(@"class->%@:%p",NSStringFromClass(class), class);
    NSLog(@"%p",[NSObject class]);

    Class r0 = object_getClass(self);
    
    while (1) {
        if (r0 == 0) {
            return 0;
        }else{
            NSLog(@"r0->%@:%p",NSStringFromClass(r0), r0);
            if (r0 != class) {
                r0 = [r0 superclass];
            }else{
                return 1;
            }
        }
    }
}
  • 驗(yàn)證結(jié)果
 BOOL res7 = [(id)[NSObject class] isKindOfClassITX:[NSObject class]];
    NSLog(@"%d",res7);
2019-09-20 15:28:49.632315+0800 sortTime[3104:232025] class->NSObject:0x10ec42ec8
2019-09-20 15:28:49.632647+0800 sortTime[3104:232025] 0x10ec42ec8
2019-09-20 15:29:34.024142+0800 sortTime[3104:232025] r0->NSObject:0x10ec42e78
2019-09-20 15:29:40.357044+0800 sortTime[3104:232025] r0->NSObject:0x10ec42ec8
  • 總結(jié):
    (1)透绩、1號(hào)[NSObject class](類對(duì)象)對(duì)應(yīng)的元類(根元類)對(duì)象和2號(hào)[NSObject class](類對(duì)象翘骂,也是根類對(duì)象)比較是否相等,如果不等.
    (2)帚豪、1號(hào)對(duì)象元類superClass指針指向的父類(此時(shí)的父類是根類對(duì)象)和2號(hào)[NSObject class](類對(duì)象碳竟,也是根類對(duì)象)比較是否相等,此時(shí)相等狸臣。

    Snip20190920_1.png

  • 驗(yàn)證 [(id)[Sark class] isKindOfClass:[NSObject class]]返回YES

    • 驗(yàn)證結(jié)果
  BOOL res7 = [(id)[Person class] isKindOfClassITX:[NSObject class]];
    NSLog(@"%d",res7);
2019-09-20 16:11:43.234421+0800 sortTime[3541:269003] class->NSObject:0x101a32ec8
2019-09-20 16:11:43.234500+0800 sortTime[3541:269003] 0x101a32ec8
2019-09-20 16:11:43.234565+0800 sortTime[3541:269003] 0x1009df9a8
2019-09-20 16:11:48.343621+0800 sortTime[3541:269003] r0->Person:0x1009df980
2019-09-20 16:11:48.343945+0800 sortTime[3541:269003] r0->NSObject:0x101a32e78
2019-09-20 16:11:48.344146+0800 sortTime[3541:269003] r0->NSObject:0x101a32ec8
  • 總結(jié):
    (1)莹桅、1號(hào)[Person class](類對(duì)象)對(duì)應(yīng)的元類3號(hào)(元類)對(duì)象和2號(hào)[NSObject class](根類對(duì)象)比較是否相等,此時(shí)不等.
    (2)烛亦、3號(hào)對(duì)象superClass指針指向的父類4號(hào)對(duì)象(此時(shí)的父類是根元類對(duì)象)和2號(hào)[NSObject class](根類對(duì)象)比較是否相等诈泼,此時(shí)不等。
    (3)此洲、4號(hào)對(duì)象(根元類)superClass指向的父類5號(hào)對(duì)象(根類對(duì)象)和2號(hào)[NSObject class](根類對(duì)象)比較是否相等厂汗,此時(shí)相等。

    Snip20190920_2.png

  • 驗(yàn)證 [[Person new] isKindOfClassITX:[NSObject class]]返回YES

    • 驗(yàn)證結(jié)果
BOOL res7 = [[Person new] isKindOfClassITX:[NSObject class]];
NSLog(@"%d",res7);
2019-09-20 16:41:06.241951+0800 sortTime[3781:288460] class->NSObject:0x10f2c0ec8
2019-09-20 16:41:06.242027+0800 sortTime[3781:288460] 0x10f2c0ec8
2019-09-20 16:41:06.242092+0800 sortTime[3781:288460] 0x60000326c520
2019-09-20 16:41:11.159426+0800 sortTime[3781:288460] r0->Person:0x10e26d9a8
2019-09-20 16:41:11.159572+0800 sortTime[3781:288460] r0->NSObject:0x10f2c0ec8
  • 總結(jié):
    (1)呜师、1號(hào)[Person new](實(shí)例)對(duì)應(yīng)的元類3號(hào)(類對(duì)象)對(duì)象和2號(hào)[NSObject class](根類對(duì)象)比較是否相等娶桦,此時(shí)不等.
    (2)、3號(hào)對(duì)象superClass指針指向的父類4號(hào)對(duì)象(此時(shí)的父類是根類對(duì)象)和2號(hào)[NSObject class](根類對(duì)象)比較是否相等,此時(shí)相等等衷畦。
    Snip20190920_3.png

isMemberOfClass

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

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末祈争,一起剝皮案震驚了整個(gè)濱河市斤程,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌菩混,老刑警劉巖忿墅,帶你破解...
    沈念sama閱讀 211,290評(píng)論 6 491
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異沮峡,居然都是意外死亡疚脐,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,107評(píng)論 2 385
  • 文/潘曉璐 我一進(jìn)店門邢疙,熙熙樓的掌柜王于貴愁眉苦臉地迎上來棍弄,“玉大人,你說我怎么就攤上這事疟游『艋” “怎么了?”我有些...
    開封第一講書人閱讀 156,872評(píng)論 0 347
  • 文/不壞的土叔 我叫張陵颁虐,是天一觀的道長蛮原。 經(jīng)常有香客問我,道長聪廉,這世上最難降的妖魔是什么瞬痘? 我笑而不...
    開封第一講書人閱讀 56,415評(píng)論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮板熊,結(jié)果婚禮上框全,老公的妹妹穿的比我還像新娘。我一直安慰自己干签,他們只是感情好津辩,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,453評(píng)論 6 385
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著容劳,像睡著了一般喘沿。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上竭贩,一...
    開封第一講書人閱讀 49,784評(píng)論 1 290
  • 那天蚜印,我揣著相機(jī)與錄音,去河邊找鬼留量。 笑死窄赋,一個(gè)胖子當(dāng)著我的面吹牛哟冬,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播忆绰,決...
    沈念sama閱讀 38,927評(píng)論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼浩峡,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了错敢?” 一聲冷哼從身側(cè)響起翰灾,我...
    開封第一講書人閱讀 37,691評(píng)論 0 266
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎稚茅,沒想到半個(gè)月后纸淮,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,137評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡亚享,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,472評(píng)論 2 326
  • 正文 我和宋清朗相戀三年萎馅,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片虹蒋。...
    茶點(diǎn)故事閱讀 38,622評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖飒货,靈堂內(nèi)的尸體忽然破棺而出魄衅,到底是詐尸還是另有隱情,我是刑警寧澤塘辅,帶...
    沈念sama閱讀 34,289評(píng)論 4 329
  • 正文 年R本政府宣布晃虫,位于F島的核電站,受9級(jí)特大地震影響扣墩,放射性物質(zhì)發(fā)生泄漏哲银。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,887評(píng)論 3 312
  • 文/蒙蒙 一呻惕、第九天 我趴在偏房一處隱蔽的房頂上張望荆责。 院中可真熱鬧,春花似錦亚脆、人聲如沸做院。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,741評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽键耕。三九已至,卻和暖如春柑营,著一層夾襖步出監(jiān)牢的瞬間屈雄,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,977評(píng)論 1 265
  • 我被黑心中介騙來泰國打工官套, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留酒奶,地道東北人蚁孔。 一個(gè)月前我還...
    沈念sama閱讀 46,316評(píng)論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像讥蟆,于是被迫代替她去往敵國和親勒虾。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,490評(píng)論 2 348

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