当前位置:   article > 正文

我也说说runtime的一道经典面试题

说说runtime

####iOS程序猿,一定见过下面这道面试题:

@implementation Son : Father  
- (id)init  
{  
    self = [super init];  
    if (self)  
    {  
        NSLog(@"%@", NSStringFromClass([self class]));  
        NSLog(@"%@", NSStringFromClass([super class]));  
    }  
    return self;  
}  
@end  

输出结果:

2017-08-09 20:46:25.013 runtime第一讲[1797:403669] Son
2017-08-09 20:46:25.013 runtime第一讲[1797:403669] Son

给super发消息,不应该输出Father么?按照我的步骤往下看,你马上就能明白这个问题。

####第一步:clang -rewrite-objc 路径/Son.m

####第二步:找到执行NSLog的代码,如下图所示:
这里写图片描述

####第三步:这两个NSLog方法有什么不同呢,分析如下:
第一个NSLog可简化为:

objc_msgSend((id)self, set_registerName("class"))

显然class消息的接受者是self,也就是Son实例。

第二个NSLog可简化为:

objc_msgSendSuper(__rw_objc_super, set_registerName("class"))

__rw_objc_super是什么东西?

这里写图片描述

哦,__rw_objc_super是一个结构体,它用来干什么?这么问没意义,你应该问这个结构体在objc_msgSendSuper方法里用来干什么?

根据苹果文档可知:__rw_objc_super结构体用来储存要接收消息的类的实例(Son),以及开始搜索方法实现的超类(Father)。

所以,objc_msgSendSuper接收消息的实际上是son,但它是从father类开始搜索class方法,由于father类并没有重载class方法,所以两次都是执行的NSObject的class方法。

所以,输出相同的Son。

不对的地方请指正,欢迎拍砖。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/爱喝兽奶帝天荒/article/detail/1022525?site
推荐阅读
相关标签
  

闽ICP备14008679号