美文网首页
runtime面试题

runtime面试题

作者: 来自蒙塔基的钢蛋儿 | 来源:发表于2019-03-15 19:23 被阅读0次

    下面是一道比较经典的runtime问题:

    
    @interface NSObject (say)
    
    @end
    
    @implementation NSObject (say)
    - (void)say{
        NSLog(@"say");
    }
    @end
    
    @interface Father : NSObject
    
    @end
    
    @implementation Father
    
    @end
    
    @interface Son : Father
    + (void)say;
    @end
    @implementation Son
    
    @end
    

    下面两行代码:

        [Son say];
        [[NSObject new] performSelector:@selector(say)];
    

    哪行运行后会crash?


    ~
    ~
    ~
    ~
    ~
    ~
    ~
    ~
    ~
    ~

    答案:

    两个方法均可以正常运行
    2019-03-15 18:32:58.773622+0800 myTest[65792:3582166] say
    2019-03-15 18:32:58.773798+0800 myTest[65792:3582166] say
    可以看到两个func say() 都没有直接实现但是确没有问题,很不符合常理


    接下来我们从Class的继承实现分析一下原因

    首先我先贴一张Class结构图:

    结构图

    网上随便找的图,接下来我们看一下他们的关系。

    [Father实例] -----isa------>[Father Class]
    -----isa------>[Father Meta]
    -----isa------>[NSObject Meta]<-----isa------>[NSObject Meta]-----isa------>
    [NSObject Class]
    

    这是一个完整的继承链,下面Son代表[Son Class]:
    1.Son 调用Say方法会去Son Meta中的MethodList中查找Say方法,结果肯定没有嘛~
    2.接下来会去Son MetaSuperClass中查找父类中是否有Say方法,还是没有~ 再看Son MetaSuperClass
    3.然后找到NSObject Meta中还是没找到Say,再看NSObject MetaSuperClass
    4.关键在这里,NSObject MetaSuperclass 指向 NSObject class ,而 NSObject Category当中实现了Say方法,所以打印成功。


    从结果反证结论是没问题的,但是明明调用的是 类方法,为什么会调用到NSObject中的 实例方法呢?
    下回再分析

    相关文章

      网友评论

          本文标题:runtime面试题

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