OC学习9——反射机制
1、OC提供了3种编程方式与运行环境进行交互:
- 直接通过OC的源代码:这是最常见的方式,开发人员只是编写OC源代码,而运行环境负责在后台工作。
- 通过NSObject类中定义的方法进行动态编程:因为绝大部分类都是NSObject的子类(NSProxy例外),所以绝大部分对象都继承了NSObject的方法,因此,所有对象都可以调用NSObject的方法来编程。例如NSObject提供了isKindOfClass:(判断指定类及其子类的实例对象)、isMemberOfClass:(判断指定类的实例对象)方法用于判断该对象所属的类;respondsToSelector:用于判断该实例是否可调用指定方法;methodForSelector:则用于返回指定方法的指针。
- 直接调用运行时函数进行动态编程:运行时系统是一个动态共享库,有一些列位于usr/include/objc目录的头文件中的函数和数据结构组成,这些工具都是C风格,他们并不是OC必需的,但有些函数在OC编程中也是有用的。
2、OC中同样也提供了与Java中类似的反射机制,这种动态变成机制可以让OC语言更加灵活。说到反射,首先我们要弄清楚什么是反射,反射的定义是运行中的程序检查自己和软件运行环境的能力,它可以根据它发现的进行改变。通俗的讲就是反射可以在运行时根据指定的类名获得类的信息。
3、为什么要用反射,也就是反射的意义何在?
- 当你做一个软件可以安装插件的功能,你连插件的类型名称都不知道,你怎么实例化这个对象呢?因为程序是支持插件的(第三方的),在开发的时候并不知道。所以,无法在代码中 New出来,但反射可以,通过反射,动态加载程序集,然后读出类,检查标记之后再实例化对象,就可以获得正确的类实例。反射的目的就是为了扩展未知的应用。比如你写了一个程序,这个程序定义了一些接口,只要实现了这些接口的dll都可以作为插件来插入到这个程序中。那么怎么实现呢?就可以通过反射来实现。就是把dll加载进内存,然后通过反射的方式来调用dll中的方法。很多工厂模式就是使用的反射。
- 在编码阶段不知道那个类名,要在运行期从配置文件读取类名,这时候就没有办法硬编码,new ClassName(),而必须用到反射才能创建这个对象。
4、每个类都有一个对应的Class,Class对象其实本质上就是一个结构体,这个结构体中的成员变量还是自己,这种设计方式非常像链表的数据结构。然后通过一个类的Class可以实现获取该类的实例变量、方法等信息,从而可以实现创建对象和调用方法的目的。
OC中获得Class通常有3种方法:
- 使用Class NSClassFromString(NSString * aClassName)函数来获取Class,该函数需要传入字符串参数,该字符串的值是某个类的类名。
- 调用某个类的class方法来获取该类对应的Class,例如 [FKPerson class]; 将会返回FKPerson类对应的Class
- 调用某个对象的class方法,该方法是NSObject类中的实例方法,所以所有的OC对象都可以调用该方法,该方法将会返回该对象所属类对应的Class。
1 | #import <Foundation/Foundation.h> |