问题

http://blog.sunnyxx.com/2014/11/06/runtime-nuts/ 问题来源。

(1) 下面的代码输出什么?

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

2016-10-10 19:01:35.752 runtimeDemo[10090:342354] Son

2016-10-10 19:01:36.244 runtimeDemo[10090:342354] Son

当调用[self class]方法时,会转化为objc_msgSend函数,这个函数定义如下:

  1. id objc_msgSend(id self, SEL op, ...)

  self:指向当前调用方法的对象。相当于 [son class];

    2.当调用[super class]方法时,会转化为objc_msgSendSuper,这个函数定义如下:

  1. id objc_msgSendSuper(struct objc_super *super, SEL op, ...)
  2. struct objc_super {
        id receiver;
       Class superClass;
    };

其实调用super,告诉编译器,调用 class 这个方法时,要去父类的方法,而不是本类里的。

步骤:1.构建objc_super结构体 receiver=son. superClass = Father;

   2.objc_msgSendSuper 将(super, op)传递

   3.objc_super->receiver 查找superClass(Father)的方法列表,如果没有找到,就去NSObject中查找,找到-class方法后,[objc_super->receiver(son)  class];

总结 SEL查找从继承体系中网上查找 但receiver不变。

(2) 下面代码的结果?

BOOL res1 = [(id)[NSObject class] isKindOfClass:[NSObject class]];BOOL res2 = [(id)[NSObject class] isMemberOfClass:[NSObject class]];BOOL res3 = [(id)[Sark class] isKindOfClass:[Sark class]];BOOL res4 = [(id)[Sark class] isMemberOfClass:[Sark class]];

YSE NO NO NO

isMemberOfClass: 判断对象是否为某个特定类的实例。

isKindOfClass: 判断对象是否为某类或派生类的实例。

+ (Class)class {
    return self;
}
调用类方法,就会通过isa找到相应的元类方法列表。
- (BOOL)isKindOf:aClass
{
    Class cls;
    for (cls = isa; cls; cls = cls->superclass) 
        if (cls == (Class)aClass)
            return YES;
    return NO;
}
这个for循环中,isa指针是一层层往上。知道NSObject为止,指向了NSObject。
BOOL res1 = [(id)[NSObject class] isKindOfClass:[NSObject class]];

NSObject 的isa指针指向本身,[NSObject class] =NSObject。
- (BOOL)isMemberOf:aClass
{
    return isa == (Class)aClass;
}
只是去比较当前isa指针。
BOOL res3 = [(id)[Sark class] isKindOfClass:[Sark class]];

根据这个for循环, 我们知道,Sark的isa指针指向NSObject  [Sark class] ==Sark.第一次不相等,之后就更不相等了。

(3) 下面的代码会?Compile Error / Runtime Crash / NSLog…?

@interface NSObject (Sark)+ (void)foo;@end@implementation NSObject (Sark)- (void)foo { NSLog(@"IMP: -[NSObject (Sark) foo]");}@end// 测试代码[NSObject foo];[[NSObject new] foo];

[NSObject foo];结果会调用-(void)foo

因为NSObject的元类的superClass ->NSObject 类  -方法和+方法,只是查找的体系不一样,但是实现原理是通过对象,找到对应的SEL即方法名去查找。

(4) 下面的代码会?Compile Error / Runtime Crash / NSLog…?

@interface Sark : NSObject@property (nonatomic, copy) NSString *name;@end@implementation Sark- (void)speak { NSLog(@"my name's %@", self.name);}@end@implementation ViewController- (void)viewDidLoad { [super viewDidLoad]; id cls = [Sark class]; void *obj = &cls; [(__bridge id)obj speak];}@end

2016-10-11 19:53:00.542 runtimeDemo[16341:945488] my name's <ViewController: 0x7fc8b3f03b70>

Propertyname最终被转换成了Ivar加入到了类的结构中,Runtime通过计算成员变量的地址偏移来寻找最终Ivar的地址。这里的原因主要是因为在C中,局部变量是存储到内存的栈区,程序运行时栈的生长规律是从地址高到地址低。C语言到头来讲是一个顺序运行的语言,随着程序运行,栈中的地址依次往下走。

转载于:https://www.cnblogs.com/JShuo/p/5950986.html

厚积薄发 - 关于runtime的几个问题相关推荐

  1. 厚积薄发,拥抱 .NET 2016

    厚积薄发这个词是高三英语老师在高考前写在黑板上,高中三年努力这么久,是时候迎面而上,冲刺向前.所以,一想到.NET 2016,脑海里蹦出的第一个词就是它. .NET 2016 是 .NET 一次质的飞 ...

  2. datagridview 手动添加的行如何进行重载_【厚积薄发】如何规划UI图标图集

    这是第151篇UWA技术知识分享的推送.今天我们继续为大家精选了若干和开发.优化相关的问题,建议阅读时间10分钟,认真读完必有收获. UWA 问答社区:answer.uwa4d.com UWA QQ群 ...

  3. 厚积薄发,丰富的公用类库积累,助你高效进行系统开发(10)---各种线程同步的集合类...

    俗话说,一个好汉十个帮,众人拾柴火焰高等都说明一个道理,有更多的资源,更丰富的积累,都是助你走向成功,走向顶峰的推动力. 本篇的公用类库的介绍主题是程序开发中多线程操作环境中,常用到的线程安全的各类同 ...

  4. 厚积薄发打卡Day75 :【MSUP】Java语言特性与设计模式(上)

    前言 在看狂神频道的时候偶然发现下图,感触颇深.特别在当今[程序 = 业务 + 框架]思想盛行的开发者中,夯实基础基础显得格外重要,因此开此专栏总结记录. 设计模式详解 设计模式的考察点,一般有2个: ...

  5. 2016net跟php哪个好,.NET_厚积薄发,拥抱.NET 2016,初识 .NET 2016 .NET 2016 概览 .NET - phpStudy...

    厚积薄发,拥抱.NET 2016 初识 .NET 2016 .NET 2016 概览 .NET 2016 作为 .NET 技术最新发展,如下图所示,它主要包含三大块: 最左边代表的是 .NET Fra ...

  6. Go 运行时(go runtime)的含义

    go 运行时,也称为 go runtime.其本身就是每个 go 程序的一部分,它会跟你的源码一起编译并连接到目标程序中.即便你只是写了一个 hello world 程序,这个程序中也包含了 runt ...

  7. Deep Learning部署TVM Golang运行时Runtime

    Deep Learning部署TVM Golang运行时Runtime 介绍 TVM是一个开放式深度学习编译器堆栈,用于编译从不同框架到CPU,GPU或专用加速器的各种深度学习模型.TVM支持来自Te ...

  8. 使用Runtime执行推理(C++)

    使用Runtime执行推理(C++) 概述 通过MindSpore Lite模型转换后,需在Runtime中完成模型的推理执行流程.本教程介绍如何使用C++接口编写推理代码. Runtime总体使用流 ...

  9. “ compiler-rt”运行时runtime库

    " compiler-rt"运行时runtime库 编译器-rt项目包括: • Builtins-一个简单的库,提供了代码生成和其他运行时runtime组件所需的特定于目标的低级接 ...

  10. runtime系统的Cello

    runtime系统的Cello 通过充当一个现代的.功能强大的runtime系统,Cello使许多以前在C中不切实际或笨拙的事情变得简单,例如: 通用数据结构 多态函数 接口/类型类 构造函数/析构函 ...

最新文章

  1. Neutron:Firewall as a Service(FWaaS)
  2. 团队-象棋游戏-开发文档
  3. 系统异常捕捉处理设计文档
  4. 在一个成熟的分布式系统中 如何下手做高可用?
  5. rsync 常见错误与解决方法整理
  6. Python 可执行对象
  7. java web----servlet
  8. Verdaccio介绍及安装 -- nodejs私有npm proxy registry代理
  9. 19个很有用的 JavaScript 库
  10. 怎样查一个文件被复制了几次_复制拷贝文件不怕再出错,一个超级好用的小工具,支持多线程工作...
  11. Java进程与子进程交互
  12. 解决Linux下chrome无法播放flash问题
  13. WPF 使用附加属性增加控件属性
  14. 一图助你搞明白Spring应用上下文初始化流程!
  15. html制作qq对话消息框,qq对话框设置 QQ聊天对话框的背景皮肤怎么设置?
  16. 如何做出优质的Scratch作品
  17. 用envi裁剪下来的图像是黑色的_ENVI进行图像裁剪.doc
  18. iOS 页面的卡顿的原因以及如何解决. 如何优化app的启动速度
  19. Android刘海屏、水滴屏全面屏适配方案
  20. Hbase2.3.5安装

热门文章

  1. MATLAB数组生成、引用
  2. TensorFlow2.0学习使用笔记
  3. C语言宏定义,内置宏的用法
  4. python2项目出现的错误(UnicodeDecodeError)
  5. SpringCloud-Config通过Java访问URL对敏感词加密解密
  6. UI_DEV_Environment 之 StoryBook
  7. 判断app访问还是web访问网站
  8. 【mysql】join的用法和修改数据表
  9. django-xadmin定制之分页显示数量
  10. 基于Web的MIS系统环境配置和相关含义(拷贝版)