runtime:是一套比较底层的纯C语言API, 属于1个C语言库, 包含了很多底层的C语言API。在我们平时编写的OC代码中, 程序运行过程时, 其实最终都是转成了runtime的C语言代码, runtime算是OC的幕后工作者。RunTime简称运行时,就是系统在运行的时候的一些机制,其中最主要的是消息机制。对于C语言,函数的调用在编译的时候会决定调用哪个函数,编译完成之后直接顺序执行,无任何二义性。OC的函数调用成为消息发送。属于动态调用过程。在编译的时候并不能决定真正调用哪个函数(事实证明,在编译阶段,OC可以调用任何函数,即使这个函数并未实现,只要申明过就不会报错。而C语言在编译阶段就会报错)。只有在真正运行的时候才会根据函数的名称找到对应的函数来调用。
实例对象instance->类class->方法method(->SEL->IMP)->实现函数runtime详解点击跳转
上图是关于isa和super_class指针的图解:
1、isa:实例对象->类->元类->(不经过父元类)直接到根元类(NSObject的元类),根元类的isa指向自己;
2、 superclass:类->父类->...->根类NSObject,元类->父元类->...->根元类->根类,NSObject的superclass指向nil。
3、Root class (class)其实就是NSObject,NSObject是没有超类的,所以Root class(class)的superclass指向nil。
4、每个Class都有一个isa指针指向唯一的Meta class
5、Root class(meta)的superclass指向Root class(class),也就是NSObject,形成一个回路。
6、每个Meta class的isa指针都指向Root class (meta)。
7、super_class表示实例对象对应的父类
8、name表示类名
9、ivars表示多个成员变量,它指向objc_ivar_list结构体。在runtime.h可以看到它的
runtime运用场景:
1.发送消息 (消息机制原理:对象根据方法编号SEL去映射表查找对应的方法实现)
2.交换方法 (开发使用场景:系统自带的方法功能不够,给系统自带的方法扩展一些功能,并且保持原有的功能,方式一:继承系统的类,重写方法.方式二:使用runtime,交换方法.)
3.动态添加方法 (开发使用场景:如果一个类方法非常多,加载类到内存的时候也比较耗费资源,需要给每个方法生成映射表,可以使用动态给某个类,添加方法解决。)补充:面试runtime:问有没有使用performSelector,其实主要想问你有没有动态添加过方法。
4.给分类添加属性 (原理:给一个类声明属性,其实本质就是给这个类添加关联,并不是直接把这个值的内存空间添加到类存空间。)
5.字典转模型 (设计模型:字典转模型的第一步 模型属性,通常需要跟字典中的key一一对应问题:一个一个的生成模型属性,很慢?需求:能不能自动根据一个字典,生成对应的属性。解决:提供一个分类,专门根据字典生成对应的属性字符串。)
注意:KVC字典转模型弊端:必须保证,模型中的属性和字典中的key一一对应。 如果不一致,就会调用[setValue:forUndefinedKey:]报key找不到的错。 分析:模型中的属性和字典的key不一一对应,系统就会调用setValue:forUndefinedKey:报错。解决:重写对象的setValue:forUndefinedKey:,把系统的方法覆盖,就能继续使用KVC,字典转模型了。
字典转模型的方式二:Runtime 思路:利用运行时,遍历模型中所有属性,根据模型的属性名,去字典中查找key,取出对应的值,给模型的属性赋值。步骤:提供一个NSObject分类,专门字典转模型,以后所有模型都可以通过这个分类转。
文/百度工程师阿伟(作者)
原文链接:http://www.jianshu.com/p/682de90106b5
著作权归作者所有,转载请联系作者获得授权,并标注“作者”。