厚积薄发 - 关于runtime的几个问题
问题
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函数,这个函数定义如下:
- id objc_msgSend(id self, SEL op, ...)
self:指向当前调用方法的对象。相当于 [son class];
2.当调用[super class]方法时,会转化为objc_msgSendSuper,这个函数定义如下:
- id objc_msgSendSuper(struct objc_super *super, SEL op, ...)
- 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;
}
- (BOOL)isKindOf:aClass
{
Class cls;
for
(cls = isa; cls; cls = cls->superclass)
if
(cls == (Class)aClass)
return
YES;
return
NO;
}
BOOL res1 = [(id)[NSObject class] isKindOfClass:[NSObject class]];
- (BOOL)isMemberOf:aClass
{
return
isa == (Class)aClass;
}
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的几个问题相关推荐
- 厚积薄发,拥抱 .NET 2016
厚积薄发这个词是高三英语老师在高考前写在黑板上,高中三年努力这么久,是时候迎面而上,冲刺向前.所以,一想到.NET 2016,脑海里蹦出的第一个词就是它. .NET 2016 是 .NET 一次质的飞 ...
- datagridview 手动添加的行如何进行重载_【厚积薄发】如何规划UI图标图集
这是第151篇UWA技术知识分享的推送.今天我们继续为大家精选了若干和开发.优化相关的问题,建议阅读时间10分钟,认真读完必有收获. UWA 问答社区:answer.uwa4d.com UWA QQ群 ...
- 厚积薄发,丰富的公用类库积累,助你高效进行系统开发(10)---各种线程同步的集合类...
俗话说,一个好汉十个帮,众人拾柴火焰高等都说明一个道理,有更多的资源,更丰富的积累,都是助你走向成功,走向顶峰的推动力. 本篇的公用类库的介绍主题是程序开发中多线程操作环境中,常用到的线程安全的各类同 ...
- 厚积薄发打卡Day75 :【MSUP】Java语言特性与设计模式(上)
前言 在看狂神频道的时候偶然发现下图,感触颇深.特别在当今[程序 = 业务 + 框架]思想盛行的开发者中,夯实基础基础显得格外重要,因此开此专栏总结记录. 设计模式详解 设计模式的考察点,一般有2个: ...
- 2016net跟php哪个好,.NET_厚积薄发,拥抱.NET 2016,初识 .NET 2016
.NET 2016 概览
.NET - phpStudy...
厚积薄发,拥抱.NET 2016 初识 .NET 2016 .NET 2016 概览 .NET 2016 作为 .NET 技术最新发展,如下图所示,它主要包含三大块: 最左边代表的是 .NET Fra ...
- Go 运行时(go runtime)的含义
go 运行时,也称为 go runtime.其本身就是每个 go 程序的一部分,它会跟你的源码一起编译并连接到目标程序中.即便你只是写了一个 hello world 程序,这个程序中也包含了 runt ...
- Deep Learning部署TVM Golang运行时Runtime
Deep Learning部署TVM Golang运行时Runtime 介绍 TVM是一个开放式深度学习编译器堆栈,用于编译从不同框架到CPU,GPU或专用加速器的各种深度学习模型.TVM支持来自Te ...
- 使用Runtime执行推理(C++)
使用Runtime执行推理(C++) 概述 通过MindSpore Lite模型转换后,需在Runtime中完成模型的推理执行流程.本教程介绍如何使用C++接口编写推理代码. Runtime总体使用流 ...
- “ compiler-rt”运行时runtime库
" compiler-rt"运行时runtime库 编译器-rt项目包括: • Builtins-一个简单的库,提供了代码生成和其他运行时runtime组件所需的特定于目标的低级接 ...
- runtime系统的Cello
runtime系统的Cello 通过充当一个现代的.功能强大的runtime系统,Cello使许多以前在C中不切实际或笨拙的事情变得简单,例如: 通用数据结构 多态函数 接口/类型类 构造函数/析构函 ...
最新文章
- Neutron:Firewall as a Service(FWaaS)
- 团队-象棋游戏-开发文档
- 系统异常捕捉处理设计文档
- 在一个成熟的分布式系统中 如何下手做高可用?
- rsync 常见错误与解决方法整理
- Python 可执行对象
- java web----servlet
- Verdaccio介绍及安装 -- nodejs私有npm proxy registry代理
- 19个很有用的 JavaScript 库
- 怎样查一个文件被复制了几次_复制拷贝文件不怕再出错,一个超级好用的小工具,支持多线程工作...
- Java进程与子进程交互
- 解决Linux下chrome无法播放flash问题
- WPF 使用附加属性增加控件属性
- 一图助你搞明白Spring应用上下文初始化流程!
- html制作qq对话消息框,qq对话框设置 QQ聊天对话框的背景皮肤怎么设置?
- 如何做出优质的Scratch作品
- 用envi裁剪下来的图像是黑色的_ENVI进行图像裁剪.doc
- iOS 页面的卡顿的原因以及如何解决. 如何优化app的启动速度
- Android刘海屏、水滴屏全面屏适配方案
- Hbase2.3.5安装