什么是runtime呢?
runtime是一套比较底层的纯c语言API,我们平时编写的OC语言代码,在程序运行过程时,都会被转化成runtime的c语言代码,runtime是oc语言的幕后工作者。
举例:
OC中的代码:
[[ZYPerson alloc]init];
在runtime中会转成这样:
objc_msgSend(objc_msgSend("ZYPerson","alloc"),"init");
什么时候会使用runtime呢?
runtime的应用时机:
1.当需要非常高的性能开发时,使用runtime,(此时OC代码已经无法满足需求)
2.当我们对系统内部的实现很好奇时,可以用clang反编译成c++去看底层实现原理。
runtime属于oc底层,可以进行一些非常底层的操作(oc是无法实现的一些方法)
runtime运用的地方:
1.在程序运行过程中,动态创建一个类(比如KVO的底层实现)
2.在程序运行过程中,动态为某个类添加属性/方法,或者修改属性值/方法。
例如:void Swizzle(Class c, SEL origSEL, SEL newSEL)
{
Method origMethod = class_getInstanceMethod(c, origSEL);
Method newMethod = nil;
if (!origMethod) {
origMethod = class_getClassMethod(c, origSEL);
if (!origMethod) {
return;
}
newMethod = class_getClassMethod(c, newSEL);
if (!newMethod) {
return;
}
}else{
newMethod = class_getInstanceMethod(c, newSEL);
if (!newMethod) {
return;
}
}
//自身已经有了就添加不成功,直接交换即可
if(class_addMethod(c, origSEL, method_getImplementation(newMethod), method_getTypeEncoding(newMethod))){
class_replaceMethod(c, newSEL, method_getImplementation(origMethod), method_getTypeEncoding(origMethod));
}else{
method_exchangeImplementations(origMethod, newMethod);
}
}
调用时:Swizzle([UIViewController class], @selector(viewDidAppear:), @selector(customViewDidAppear:));这种方法就是利用runtime机制去动态修改系统的viewDidAppear方法。
3.遍历一个类所有的成员变量(属性)/所有方法。
例如:我们需要对一个类的属性进行归档解档的时候属性特别的多,这时候,我们就会写很多对应的代码,但是如果使用了runtime就可以动态设置!
学习runtime机制首先要了解一下几个问题:
1.相关的头文件和函数
>查看<objc/runtime.h>头文件,我们可以查看runtime的各种使用方法。
2.相关的应用场景
>NSCoding(归档和接档,可以利用runtime快速遍历模型对象的所有属性)。
>字典->模型(利用runtime遍历模型对象的所有属性,根据属性名从对应字典中取出对应值,设置到模型的属性上)
>KVO(利用runtime动态生成一个类)
>用于封装框架(可以完全自定义,想怎么改就怎么改)
3.相关的函数
>objc_msgSend: 给对象发送消息
>class_copyMethodList: 遍历某个类所有的方法
>class_copyIvarList: 遍历某个类所有的成员变量(属性)
>class_...
4.必备常识
> Ivar : 成员变量
> Method : 成员方法
从上面例子中我们看到我们定义的成员变量,如果要是动态创建方法,可以使用Method,