频道栏目
首页 > 程序开发 > 移动开发 > 其他 > 正文
我也说说runtime的一道经典面试题
2017-08-11 10:34:00      个评论    来源:我是小小的搬运工  
收藏   我要投稿

我也说说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。

点击复制链接 与好友分享!回本站首页
上一篇:数字签名与数字证书
下一篇:ImageLoader的使用
相关文章
图文推荐

关于我们 | 联系我们 | 广告服务 | 投资合作 | 版权申明 | 在线帮助 | 网站地图 | 作品发布 | Vip技术培训 | 举报中心

版权所有: 红黑联盟--致力于做实用的IT技术学习网站