runtime
RunTime
runtime一般都是在针对系统的类的时候使用
RunTime,消息进行时,我们平时写的oc代码,编译运行后,都会被系统转化为c++代码。
runtime的特性就是消息传递,代码方法的执行的本质就是消息的传递(发送消息)。
在xcode5之后苹果runtime代码不再有提示,苹果不希望底层代码展露出来。想使用的话,就要在工程中的build setting中搜索msg,将属性改为NO,然后在代码中导入<objc/messgae.h>,不用导入<objc/runtime.h>,因为前者中导入了后者。
简单使用如下
1.runtime使用起来比oc代码繁琐一些,所以一般还是不需要使用。但时使用oc代码是调用不了其他类的私有方法的,如果想调用私有方法,那么就可以使用runtime来调用方法。没找到私有方法,runtime就会去底层代码找,完成调用其他类的私有方法操作。
2.runtime(交换方法)。
需求:比如说有一个项目,已经开发了两年,突然项目负责人要求添加一个功能,每次UIImage加载图片,告诉我是否加载成功。
方法一:自定义UIImage
方法二:给UIImage添加分类
方法三:runtime交换方法
前两种弊端:1.每次使用,都需要导入 2.项目大了,没办法逐一更改实现
故需要使用runtime实现,使用runtime的交换方法:method_exchangeImplementations(method1, method2);传入的两个方法,在以后的使用中,如果调用方法一,就会实现方法二的代码,如果调用方法二,就会实现方法一的代码。通过这个交换功能,可以满足需求。
首先还是要给image写一个分类,然后写出以下代码,如图
然后以后直接就调用UIImage imageNamed方法就可以了,满足需求
3.runtime(动态添加方法)
对于oc中的方法调用,就个人理解,说下直接调用方法和通过performSelector调用方法的区别。
直接调用直接调用方法时,调用之前需要实现并导入该方法,不然编译就会报错。而performSelector方法调用方法,他在编译的时候不会检查方法是否存在,而是运行的时候去寻找方法,运行之前也不需要导入。oc都是懒加载机制,只要有一个方法实现了,就会添加到方法列表中。如果有一些方法比较复杂,而且不常用,那么就可以先不实现,然后通过performSelector调用的时候动态添加方法。
如图,在外界调用Person类没有实现的eat方法,在Person类中只要这么处理,动态添加方法就可以了。
在外界使用performSelector调用eat方法,运行的时候,会发现没有实现这个方法,然后进入Person类的resolveInstanceMethod:(SEL)sel方法,对在外界调用的方法名进行判断,匹配上之后,就使用runtime的动态添加方法,class_addMethod();该方法最后一个参数是传入要添加的方法的方法类型。类型可以在官方文档中查看怎么表示。这里的v表示void,@表示object(id 的意思),:表示SEL(方法标识)。 完成之后,在外界调用Person类的eat方法的时候,就会去执行aaa方法中的代码了!
4.runtime 动态添加属性
什么时候需要动态添加属性:给系统的类添加属性,可以使用runtime动态添加属性方法。 本质:动态添加属性,就是让某个属性与对象产生关联 需求:让一个NSObject类 保存一个字符串
步骤:想让NSObject类有一个name属性,保存我们传进的参数字符串。首先先给NSObject写一个分类,创建一个name属性;然后在分类的实现中给name属性写set和get方法。如图
然后在外界就可以直接给NSObject对象的name属性赋值了。