RunTime简称运行时,是运行时的一些机制,最主要的是消息机制。因为oc中只有对象能发送消息,所以一般以objc开头。
对于c语言,函数在编译是就会决定调用,而oc中不会,oc的函数属于一种动态调用。举例说明,oc中只声明一个方法并不去实现它,然后直接调用,编译夺得时候不会报错,只有在运行时报错。类似的情况,在c中是不能通过编译的。
简单归纳一下RunTime的功能:发送消息,交换方法的实现,动态添加方法,给分类添加属性以及字典转模型。
使用消息机制的前提是头文件导入#import <objc/runtime.h>(有些人喜欢用<objc/message.h>后者内部导入了前者)
发送消息:objc_msgSend(类或者对象 @selector(方法名));比较简单,与普通的oc基本一样。
交换方法:当系统自带的方法功能不够,需要给系统的类添加方法,并保持原有的功能。
第一种方法:继承系统的类,重写系统的方法,实现功能后再导入该文件。然后调用方法。
第二种方法:runtime方法,创建一个分类,在分类中实现一个方法,使用runtime交换该方法与原方法的实现。(不能在分类中重写系统的方法否则会覆盖系统的原方法,也不能在分类中调用super);
动态添加方法: 关键字performSelector 关健方法:+(BOOL)resolveInstanceMethod:(SEL)sel
当对象调用没有实现的方法,就会进入该方法,并且会把对应的方法列表传过来。
介绍一下方法列表:methodList 对象方法保存在类中,类方法保存在元类(meta class)中。
方法的查找:根据对象的isa去对应的类中查找,根据方法的编号SEL,在方法列表中找到对应方法名,再根据方法名找到实现。
由此我们可以在该方法中判断一下没有实现的方法是不是我们想添加导入方法如果是,再使用class_addMethod方法添加一个方法,然后实现这个方法即可,最后还要return [super resolveInstanceMethod:sel];保持系统原有的做法。
给分类添加属性:都知道,分类是不能生成属性和成员变量的,只能给原类扩充方法。所以我们做的本质上是给类添加关联,不是直接把添加的属性放到原类的内存空间。要完成这个功能我们需要知道一个方法:
objc_setAssociatedObject(<#id object#>, <#const void *key#>, <#id value#>, <#objc_AssociationPolicy policy#>)第一个参数:给哪个类添加关联(属性)2:相关联的key 自己创建一个key 3:关联的值 属性名 4关联的策略
比如我要给某个分类t添加属性name [email protected]"sun"(value) 然后static const NSString * [email protected]"name"(key)
重写name的get方法-(NSString *)name{reture objc_getAssociatedObject(self,key)};
最后重写name的set方法,在里面调用setAss方法将key value等参数写好就创建了关联。