「这是我参与2022首次更文挑战的第16天,活动详情查看:2022首次更文挑战」。
先验证一下父类的关系:
Student类的父类 = Person类,Person类的父类 = NSObject,NSObject的父类= nil,打印StudentSup 和Person1的地址,PersonSup和Object1的地址,ObjectSup的地址\
Student元类的父类 = Person元类,Person元类的父类 = NSObject的元类,NSObject元类的父类 = NSObject类,打印StudentMetaSup和PersonMeta的地址,PersonMetaSup和ObjectMeta的地址,ObjectMetaSup和Object1的地址
验证isa 关系
- 先看Student的isa指向。
Student的实例isa = Student类,Student类isa = Student元类,Student元类isa = NSObject元类,打印Student和Student1的地址,StudentMeta1和StudentMeta的地址,StudentMetaIsa和ObjectMeta的地址
- 再看Person的isa指向。
Person的实例isa = Person类,Person类isa = Person元类,Person元类isa = NSObject元类,打印Person和Person1的地址,PersonMeta1和PersonMeta的地址,PersonMetaIsa和ObjectMeta的地址
-
最后看NSObject的isa指向
NSObject的实例isa = NSObject类,NSObject类isa = NSObject元类,NSObject元类isa = NSObject元类,打印Object和Object1的地址,ObjectMeta1和ObjectMeta的地址,ObjectMetaIsa和ObjectMeta的地址
最后验证一下所有元类的isa 都指向根元类,打印`ObjectMetaIsa,PersonMetaIsa,StudentMetaIsa`的地址\
所有元类的isa指向根元类
验证完毕,都符合图中的指向关系。
这里还有一个好玩的地方,不知道大家注意没有,NSObject元类的父类是NSObject类。众所周知类方法是存储在元类里的,所以当你调用一个类方法,会在元类里面顺着关系链去找这个方法,如图,当在NSObject元类里找不到类方法时,会转到NSObject类里去找,而NSObject类里存储的是实例方法,这意味着如果通过类方法的方式调用NSObject类里的实例方法,也是可以的。
试一试。 NSObject里有一个实例方法methodForSelector,给Person类也加一个实例方法-(void)sayHello;。
可以看到编译器允许methodForSelector的调用,并能够正常运行。
而sayHello,则会编译错误。
分析就到这里,有误请大佬指正。