一直认为Runtime是一个高深莫测的东西,今天开始正式学习一下什么是Runtime,来揭开它的神秘面纱。
介绍
Objective-C
是一门动态语言,它将编译时和链接时的事情推迟到运行时来处理。它可以动态的完成任务。这意味着该语言不仅需要编译器,还需要运行时系统来执行编译的代码。运行时充当了Objective-C
的一种操作系统,这就是为什么这个语言可以正常的工作。
下边将介绍NSObject
类以及Objective-C
如何与runtime
进行交互。特别是,它检查了运行时动态加载新类,并且将消息转发给其他的对象。它还提供了有关如何在程序运行时查找有关对象的信息。
阅读此文档你可以了解到Objective-C在运行时系统如何工作。通常情况下,你并不需要知道和理解这些,就可以编写一个app。
版本和平台
在不同的平台有不同版本的Objective-C
的runtime
.
Objective-C
有两个版本modern
和legacy
。在Objective-C 2.0
引入了modern
版本,并包含了很多新的功能。Objective-C 1
运行时参考中描述了legacy
运行时的编程接口; Objective-C Runtime Reference. 参考中描述了现代版运行时的编程接口。在iPhone App
和64位的Mac OS X 10.5
及以上系统上使用的是modern
版本,其他是的legacy
版本,我们现在没必要再管legacy
了。
值得注意的是实例变量在modern
版本中是non-fragile
的
- 在
legacy
版本中,如果要更改实例变量的布局,则必须重新编译从其继承的类 - 在
modern
版本中,如果要更改实例变量的布局,则不必重新编译从其继承的类
与runtime进行交互
Objective-C
程序与运行时系统在三个不同的层次上进行交互:通过Objective-C
源代码; 通过Foundation
框架中NSObject
类中定义的方法以及通过对Runtime
库函数的直接调用。
通过 Objective-C 源代码
在大多是情况下,我们只需要编写和编译Objective-C
的源代码。runtime
系统自动的在幕后运行并把我们编写的源代码在编译阶段转换成运行时的代码,在运行时确定对应的数据结构和调用具体哪个方法。
编译包含Objective-C
类和方法的代码时,编译器将创建实现该语言动态特性的数据结构和函数调用。数据结构通过class
、category
定义以及protocol
声明来获取信息,他们包含class
和协议对象以及selector
实例变量以及其他信息,runtime中最终的就是发送消息的功能,它由源代码消息表达式调用。
通过 Foundation 框架的 NSObject 类定义的方法
Cocoa
中绝大多数对象都是NSObject
的子类,所以大多数的对象都继承了它定义的方法。(值得注意的是NSProxy
类,参见Message Forwarding 消息转发了解更多信息)。因此,它的方法简历行为是每一个实例和每个类对象固有的。但是在少数情况下,NSObject
只是定义了一个模板,它并没有提供所有必要的代码。
例如,NSObject
类定义了一个description
实例方法,它返回一个描述类内容的字符串。这主要用于调试GDB print-object
命令打印从此方法返回的字符串。NSObject
这个方法的实现不知道这个类包含了什么,所以它返回一个对象名字和地址的字符串。NSObject
子类可以实现这个方法来返回更详细的信息。例如,NSArray
返回它包含的对象的描述列表。
有的NSObject
方法只是查询运行时的信息。这些方法允许对象进行自省。这样的方法是类方法,该方法要求对象识别自己是哪个类。isKindOfClass:
和isMemberOfClass:
它来测试对象在继承层次结构中的位置。respondsToSelector:
它表示一个对象是否可以接受一个特定的消息;conformsToProtocol
他表示一个对象是否要实现特定协议中定义的方法;methodForSelector:
它提供了一个方法实现的地址。像这些方法给了一个对象自省的能力。
自省是对象的固有能力,即程序运行时,对象可根据请求对外透露自身基本特性。 您可以给对象发送某种消息,向其询问与它自身相关的问题,对象在Objective-C 运行时将会向您提供答案。自省是很重要的编码工具,它可以让程序变得更加高效健壮.
通过对 Runtime 库函数的直接调用
运行时系统是一个动态共享库,它包含了一个公共的接口,它包含在目录/usr/include/objc
中的头文件中的一组函数和数据结构。在Objective-C
编程时我不需要用这些,但是有些运行时的功能还是很有用的,关于库函数可以在Objective-C Runtime Reference中查看Runtime
的详细文档。
文章如有错误希望大家指出,共同学习,共同进步。