美文网首页
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