iOS小知识之类的继承关系

287 阅读3分钟

小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。

我们知道任何一个类,都会有它的继承关系。那类的元类继承于谁呢?它的父类又会是谁呢?我们通过一些简单的代码来探索一下。
创建一个类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