美文网首页
iOS 根元类的父类

iOS 根元类的父类

作者: 言霏 | 来源:发表于2020-07-01 17:40 被阅读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掉。

    相关文章

      网友评论

          本文标题:iOS 根元类的父类

          本文链接:https://www.haomeiwen.com/subject/ntqhqktx.html