OC runtime
参考文档:https://juejin.im/post/6844903586216804359
参考文档:https://hit-alibaba.github.io/interview/iOS/ObjC-Basic/Runtime.html
消息在对象中响应,消息必须在对象的类协议描述中定义,该对象才能响应消息。
方法是消息的详细实现。类协议描述中包括了每个消息的方法细节。
Objective-C 是C语言的扩展,加入了面向对象和Smalltalk式的消息传递机制。扩展的核心是用C语言和编译语言写的runtime库,它是Objective-C 面向对象和动态机制的基础。
Objective-C 是一个动态语言,这意味着它不仅需要一个编译器,也需要一个运行时系统来动态得创建类和对象、进行消息传递和转发。
Runtime其实有两个版本: “modern” 和 “legacy”。我们现在用的 Objective-C 2.0 采用的是现行 (Modern) 版的 Runtime 系统,只能运行在 iOS 和 macOS 10.5 之后的 64 位程序中。而 macOS 较老的32位程序仍采用 Objective-C 1 中的(早期)Legacy 版本的 Runtime 系统。这两个版本最大的区别在于当你更改一个类的实例变量的布局时,在早期版本中你需要重新编译它的子类,而现行版就不需要。
高级语言变为可执行文件,编译 -> 汇编语言 -> 机器语言,机器语言是计算机识别的唯一语言。
OC 与其它高级语言不同: OC 线转换为 -> 纯C语言 -> 编译 -> 汇编语言 -> 机器语言. 从OC到C语言的过渡就是由runtime来实现的.
对于实例变量有如下的思路:
instance -> class -> method -> SEL -> IMP -> 实现函数
实例对象中存放 isa 指针以及实例变量,有 isa 指针可以找到实例对象所属的类对象 (类也是对象,面向对象中一切都是对象),类中存放着实例方法列表,在这个方法列表中 SEL 作为 key,IMP 作为 value。 在编译时期,根据方法名字会生成一个唯一的 Int 标识,这个标识就是 SEL。IMP 其实就是函数指针 指向了最终的函数实现。整个 Runtime 的核心就是 objc_msgSend 函数,通过给类发送 SEL 以传递消息,找到匹配的 IMP 再获取最终的实现。
SEL 与 IMP 的关系非常类似于 HashTable 中 key 与 value 的关系。OC 中不支持函数重载的原因就是因为一个类的方法列表中不能存在两个相同的 SEL 。但是多个方法却可以在不同的类中有一个相同的 SEL,不同类的实例对象执行相同的 SEL 时,会在各自的方法列表中去根据 SEL 去寻找自己对应的IMP。这使得OC可以支持函数重写。
posted on 2020-11-19 13:55 东方🐺 阅读(120) 评论(0) 编辑 收藏 举报