Runtime是什么
简单的说,Runtime的内容包括两个部分:
1.消息分发。
2.在运行时对代码进行动态的修改。
消息分发放到后面介绍。
现在介绍对代码的动态修改。
在日常的开发过程中,如果我们想要对数据进行持久化,我们可以使用数据库来达到目的。数据库能够提供对数据的增,删,查,改的能力。例如通过Insert into 来插入,通过delete来删除,select来查找,update来更新。既然可以对数据进行增删查改,那么是否有一种方式能够对代码进行同样的增,删,查,改呢?确实是有的,OC中的Runtime实际上就提供了这样一种对运行时的代码进行变动的能力。
注意:runtime并不是通过直接修改已有的代码来实现这样的能力。
现在让我们来看一下Runtime具体能够实现的功能,它包括:
- 获取类的信息
通过Runtime知道一个类的属性(包括私有属性),类的方法(包括私有方法和Category生成的方法)。 - 修改类的实现
关联一个属性,修改一个属性。
改变一个方法的实现,添加一个方法,替换一个方法。 - 添加一个类
动态的添加一个类,替换一个类,删除一个类。
可以看出,Runtime作用的对象为我们日常编写的源代码文件。其能够实现的功能就是对源文件进行增、删、查、改。这样看起来和数据库也没有太多的不一样。
Runtime可以做什么
我们现在已经知道Runtime所能提供的能力了,它能够提供给我们对代码进行改动的能力。这种能力看起来也太稀疏平常了。对代码的修改直接在源文件中进行不就好了么,干嘛还要使用Runtime?
考虑一下这样的场景,当使用一个没有源代码的第三方库时,如果想要改动里面一个方法的实现,这个时候就只能依靠Runtime了。Runtime能够在没有源码的情况下修改一个类。由此可以看出关键在于没有源码这几个字。
当然,使用Runtime并不仅仅只是因为没有源码,有时候在有源码的情况下,也会使用Runtime。这个时候使用Runtime是因为它能够帮助实现代码解耦或一些其他的原因。
总的来说,就目前所能看到的情况总结下来Runtime的使用场景有以下几种:
- 为已有的类关联属性
- 方法替换
- 切片编程(AOP)
- 键值监听(KVO)
- 对象关系映射(ORM)和桥协议
- 热修复
- 私有函数的调用
Runtime注意事项
在使用数据库的时候,需要注意脏读,幻读等问题。这些问题都是由于并发操作引起的。实际上在使用Runtime的时候也会遇到类似的问题。如果对于启动时间要求不那么苛刻的情况,可以考虑将Runtime所做的动作放到+load中间去执行。