iOS 根元类的父类

2020-07-01  本文已影响0人  言霏
官方例图.png

上图可以得知

每个类都有自己特有的类对象、元类,父子类的类对象、元类也为父子关系。
类对象的父类最终会指向nil,而元类的父类最终指向了根的类对象。

有如下代码:

@interface NSObject (sport)
/// 给NSObject添加类方法声明
+(void)run;

@end

@implementation NSObject (sport)
/// 实现却是实例方法
- (void)run {
    NSLog(@"run.....");
}
@end

- (void)viewDidLoad {
    [super viewDidLoad];
    // 调用
    [NSObject run];
}

输出:
2020-07-01 15:49:04.075158+0800 Demo[7175:1743450] run.....

明明调用的是NSObject的类方法,但是最终却调用到了实例方法,why……
结合上图,NSObject就是根类对象Root class(class),当调用[NSObject run]时会根据其isa指针找到根元类Root class(meta),但是根元类中并没有方法run方法(元类中只会储存类方法的实现),接着会到根元类的父类根类对象Root class(class)中查找,而其中确有run方法,就这样实例方法被调用到了。
实际上所有NSObject的实例方法都可以通过调用类方法的形式进行调用,并且如下可以调用:

[UIViewController run];
[UIColor run];
[UIButton run];

但是注意一下情况:

@interface UIViewController (sport)

+ (void)jump;

@end

@implementation UIViewController (sport)

- (void)jump {
    NSLog(@"jump.....");
}

@end

- (void)viewDidLoad {
    [super viewDidLoad];
    // 调用
    [UIViewController jump];
}

此时[UIViewController jump]就会crash,UIViewController相当于上图中的类对象Superclass(class),调用jump会去其isa指向的元类Superclass(meta)中寻找-没有,去元类的父类Root class(meta)寻找-没有,再去其父类Root class(class)寻找也没有,因为jump方法是在类对象Superclass(class)中保存的,最终crash掉。

上一篇下一篇

猜你喜欢

热点阅读