(1)什么是Runtime ?(当然Runtime 还有很多用,我所说的只是它的冰山一角)
听着很高大尚的样子,其实很多时候我们都在用,只不过,你不知道而已:那么我们来简单了解一下什么是Runtime,我们都知道Object-C 是根据C语言所衍生出来并增加了面向对象概念的语言.
然而OC和其他面向对象的语言还是有区别的,比如在其他语言里面叫做方法调用,而在OC里面叫做给对象发送消息.并且OC 把数据类型的确定有编译时推迟到了运行时,我们平常调用方法 [recive message];并不会马上执行message这个方法,而是向recive 发送一个message消息.
我们平常在程序里很容易遇到一种情况,需求一直在改,不知道什么时候,和后台商量好的东西,过了个周末,变得面目全非,貌似是流星撞了地球,而你还傻乎乎找问题出在哪?,有时候甚至导致程序直接崩溃,当然一个资深的程序员,会想到这种情况,做各种判断,哪还有没有其他什么更好的办法呢.当然是有的,刚才也说了,程序崩溃无非是给对象发送了一个他处理不了的问题,比如:向一个数组添加一个nil 元素;
(2)问题解决-思路
既然是向对象发送了一个不可处理的消息(上述图片中:是向可变数组arry 发送一条 addObject 的消息),那么我们能不能在他们发送消息的时候,改变一下,如果是处理不了的消息,消息就不转发,而是在控制台打印一条信息:告诉我们奔溃原因呢.--答案当然是可以的:例如--利用Method Swizzling==>在程序运行的时候交换两个方法的调用,例如程序要调用 addObject这个方法,那么我们让程序先调用一下自己的方法,
(3)问题解决-如何实现
1.先打开你的程序,看一下崩溃信息,里面有一个reason 如果你的程序是因为数组越界(取值范围超出数组的元素个数--常见问题)而崩溃,那么控制台会打印出-[__NSArrayM objectAtIndex:]: index 1000 beyond bounds for empty array
2.记住上面的 信息 会用到: 我们现在就让系统的方法,和咱们自己写的方法进行交换,那么如何交换呢:首先我们要拿到这个方法,通过class_getInstanceMethod获取实例方法.(当然也有获得类方法的 class_getClassMethod)(我们需要导入一个头文件:#import <objc/runtime.h>)
这样就拿到系统中的objectAtIndex方法(因为超出数组元素个数而崩溃),通过这个方法,再去拿到我们自己写的方法,与之交换调用时机.
DEMO链接: 点击进入gitHub
* 使用方法
```
把DEMO中 类目 文件夹里的文件拷贝到你的项目中,不需要引入不需要做其他任何事情.然后编译之后,没有错误,试一下数组越界,会不会崩溃,如果没有崩溃,集成完毕.
```