Objec-C 反射机制

本人理解可能不是很全面,或者有不正确的地方,希望大家能帮忙纠正

反射是计算机程序在运行时检查,内省,修改自身结构和行为的一种能力,这种能力可以让一个给定的程序动态的适应不同的情况, Objective-C也提供了类似于Java的反射机制,这种动态编程机制可以让objective-c语言更加灵活
说的再通俗一点反射机制是在编译并不确定是哪个类被加载了,而是在程序运行的时候才加载、探知、自审。使用在编译期并不知道的类。这样的特点就是反射。

Objective-C提供了3种编程方式与运行环境交互

  • 直接通过objective - c 的源代码,这是最常见的方式,开发人员编写源代码,而运行环境负责后台工作,当编译objective-c源代码的时候,编译器会创建大量的数据结构和动态机制的函数
  • 通过NSObject类中定义的方法进行动态编程,。因为绝大部分类都是NSObject的子类(NSProxy例外),所以绝大多部分对象都继承了NSobject的方法,故所有的对象都可以直接调用NSObject的方法来编程,在少数情况下,NSObject类只提供了方法模板,并没有为方法实现提供代码。例如,NSObject实现了description方法,该方法返回对象的类名+地址组成的字符串,通过该字符串拉来描述对象,而NSObject的子类则可重写该方法返回更多的详细信息。除此之外,NSObject还提供了isKindOfClass:、isMemberOfClass:方法,这两个方法可用于判断该对象所属的类;respondsToSelector:用于判断该实例是否可调用指定方法;conforms
  • 直接调用运行时函数进行动态编程。运行时系统十一个动态共享库,由一系列位于/usr/include/objc目录的头文件中的函数和数据结构组成,这些工具都是C风格的,它们并不是Objective-C编程必需的,但有些函数在Objective-C编程是也是有用的。如果需要理解这些运行时函数的功能和用法,可参考Xcode帮助系统的Objective-C Runtime Reference帮助手册。

那么反射有什么作用呢?

假如我们有两个程序员,一个程序员在写程序的时候,需要使用第二个程序员所写的类,但第二个程序员并没完成他所写的类。那么第一个程序员的代码能否通过编译呢?这是不能通过编译的。这时候就可以利用反射的机制就可以让第一个程序员在没有得到第二个程序员所写的类的时候,来完成自身代码的编译。

再例如,NSObject实现了description方法,该方法返回对象的类名+地址组成的字符串,通过该字符串拉来描述对象,而NSObject的子类则可重写该方法返回更多的详细信息。这就是利用了反射的原理,是对我们创建对象的探知、自审。

反射能做什么#

  • 在运行时判断任意一个对象所属的类;

  • 在运行时构造任意一个类的对象;

  • 在运行时判断任意一个类所具有的成员变量和方法;

  • 在运行时调用任意一个对象的方法;

  • 生成动态代理

要正确使用反射机制就得使用获取Class,它是反射机制的起源

当一个类被加载以后,就会自动产生一个Class对象。通过这个Class对象我们就能获得Class对象对应的方法、成员以及构造方法的声明和定义等信息。

Clas对象其实本质上就是一个结构体,这个结构体中的成员变量还是自己,这种设计方式非常像链表的数据结构。

  1. *使用NSClassFromString(NSString aClassName)函数来获取Class,该函数需要传入字符串参数,该字符串参数的值是某个类的类名例 NSClassFromString(@“NSString ”)
  2. ** 通过某个实例本身来获取class,self.class**
  3. **通过某一个类的class的方法,咧[NSString Class]; **

反射方法
在Objection中Foundation框架为我们提供了一些方法反射的API,我们可以通过这些API执行将字符串转为SEL等操作

// SEL和字符串转换
FOUNDATION_EXPORT NSString *NSStringFromSelector(SEL aSelector);
FOUNDATION_EXPORT SEL NSSelectorFromString(NSString *aSelectorName);
// Class和字符串转换
FOUNDATION_EXPORT NSString *NSStringFromClass(Class aClass);
FOUNDATION_EXPORT Class __nullable NSClassFromString(NSString *aClassName);
// Protocol和字符串转换
FOUNDATION_EXPORT NSString *NSStringFromProtocol(Protocol *proto) NS_AVAILABLE(10_5, 2_0);
FOUNDATION_EXPORT Protocol * __nullable NSProtocolFromString(NSString *namestr) NS_AVAILABLE(10_5, 2_0);

在Object - C 中,关于反射的实例#

  1. 获取一个类的所有属性
    例如 :在MVC 模式中给Mode添加如下方法 以后可以直接使用NSLog打印mode对象里面所有属性值
-(NSString *)description
{

    // 运行时 获取对象属性

    NSMutableArray *returnarry =[[NSMutableArray alloc] init];
    unsigned int  count = 0;
   objc_property_t *prolist = class_copyPropertyList([self class], &count);
    // 遍历所有数组 从数组中取得所有的属性
    for (int i=0; i

例如 : 字典转模型
http://www.jianshu.com/p/7ec23314a830

  1. 通过反射机制实例化一个类的对象
    例如:通过字符串创建实例
  Class classname =NSClassFromString(@"HPServiceVC");
    UIViewController *controller =[[classname alloc] init];

例如:反射机制应用于工厂模式
< — 刘小壮> http://www.jianshu.com/p/a523144d8d7a

  1. 通过反射机制调用某个类的方法
    例如:通过反射调用 addObject
  NSMutableArray *arry =[[NSMutableArray alloc] init];
    
   // [arry addObject:@"hah"];
    [arry performSelector:NSSelectorFromString(@"addObject") withObject:@"hah"];
  1. 利用反射做组件开发
    目前正在学习中,待完善

你可能感兴趣的:(Objec-C 反射机制)