iOS小知識之類的繼承關係

語言: CN / TW / HK

小知識,大挑戰!本文正在參與“程式設計師必備小知識”創作活動。

我們知道任何一個類,都會有它的繼承關係。那類的元類繼承於誰呢?它的父類又會是誰呢?我們通過一些簡單的程式碼來探索一下。\ 建立一個類LGPerson繼承於NSObject,那麼LGPerson元類的父類是誰呢?\ 首先我們先列印一下NSObject的isa走點陣圖

``` // NSObject例項物件 NSObject *object1 = [NSObject alloc]; // NSObject類 Class class = object_getClass(object1); // NSObject元類 Class metaClass = object_getClass(class); // NSObject根元類 Class rootMetaClass = object_getClass(metaClass); // NSObject根根元類 Class rootRootMetaClass = object_getClass(rootMetaClass); NSLog(@"\n%p 例項物件\n%p 類\n%p 元類\n%p 根元類\n%p 根根元類",object1,class,metaClass,rootMetaClass,rootRootMetaClass);


//輸出結果為: 0x100792150 例項物件 0x7fff807c2088 類 0x7fff807c2060 元類 0x7fff807c2060 根元類 0x7fff807c2060 根根元類 `` 再列印LGPerson`元類的父類

``` // LGPerson元類 Class pMetaClass = object_getClass(LGPerson.class); //LGPerson元類的父類 Class psuperClass = class_getSuperclass(pMetaClass); NSLog(@"%@ - %p",psuperClass,psuperClass);


//輸出結果為 NSObject - 0x7fff807c2060 `` - 通過輸出地址發現,LGPerson元類的父類並不是NSObject,而是NSObject`的元類,即:根元類


我們是不是可以得出一個結論:元類的父類是根元類。我們用層級更深的繼承鏈去驗證。\ 建立LGTeacher繼承於LGPersonLGPerson繼承於NSObject,列印LGTeacher的繼承鏈。首先列印下LGPerson的isa走點陣圖

``` // LGPerson元類與根元類 Class pMetaClass = object_getClass(LGPerson.class); Class pRootMetaClass = object_getClass(pMetaClass);

NSLog(@"%p LGPerson元類\n%p LGperson根元類",pMetaClass,pRootMetaClass);


//輸出結果為: 0x100008338 LGPerson元類 0x7fff807c2060 LGperson根元類 `` 列印LGteacher`元類的父類

``` // LGTeacher -> LGPerson -> NSObject // 元類也有一條繼承鏈 Class tMetaClass = object_getClass(LGTeacher.class); Class tsuperClass = class_getSuperclass(tMetaClass);

NSLog(@"%@ - %p",tsuperClass,tsuperClass);


//輸出結果為: LGPerson - 0x100008338

`` - 發現LGTeacher元類的父類,指向其父類LGPerson`的元類


結論: - 元類的父類是根元類的結論是錯誤的 - 其元類的父類繼承於其父類的元類,其父類的元類繼承於其根元類 那NSObject呢?又是什麼情況呢? 我們列印一下根類與根元類

``` // NSObject 根類特殊情況 Class nsuperClass = class_getSuperclass(NSObject.class); NSLog(@"%@ - %p",nsuperClass,nsuperClass);

// 根元類 -> NSObject Class rnsuperClass = class_getSuperclass(metaClass); NSLog(@"%@ - %p",rnsuperClass,rnsuperClass);


//輸出結果為: (null) - 0x0 NSObject - 0x7fff807c2088 `` 可以得出結論: -NSObject作為根類,沒有父類,或者說父類為nil - 根元類的父類指向根類,即:NSObject` 所以我們可以這樣總結: - 根類繼承鏈:根類 -> nil - 根元類的繼承鏈:根元類 -> 根類 -> nil

image-6.png 我們可以得出如下繼承關係: - 類的繼承鏈:類 -> 父類 -> 根類 -> nil - 元類的繼承鏈: 元類 -> 父類的元類 -> 根元類 -> 根類 -> nil - 繼承關係只來自於類,物件之間沒有這層關係 - NSObject作為根類,它擦拭真正的萬物之主,所有類都源於NSObject