Objective-C的反射

原创 2012年03月22日 16:24:26

我第一次接触Java的时候就觉得整个反射包都很新颖,它使得Java和解释型的脚本语言更接近了,与此同时也拉开了和主流的C和C++的距离。在运行时可以窥视到一个对象的类元数据真的很不可思议,尽管这些可能不会在日常应用编程中经常使用到。从Java转到Objective-C的程序员应该会乐见Objective-C也支持反射。实际上,Objective-C有很多诸如动态改变类定义以及创建一个新类的动态特征。不过很难说这些功能有多大的作用,这也让我觉得Objective-C是一个有些臃肿的语言。在我看来,Objective-C有一个定位危机:它是解释型语言还是编译语言?运行时很大程度上是动态的。和C++不同,Objective-C是运行时绑定的。这也是为什么我们可以在实现时定义一个从来没有在头文件中声明的方法,或者通过Category扩展类。不幸的是由于这种臃肿使得找到一些日常编程中有用的东西变得困难,本文就是要去发现其中的一些“宝藏”。

根类NSObject

   大部分(如果不是全部的话)的动态反射支持来自NSObject类。和Java的Object对象类似,NSObject是所有类(除了一些很少见的例外)的根类。所以所有你写的类应该都可以支持反射。需要指出的所有这些的反射支持并不是Objective-C语言的一部分,而是源于NS*的运行时环境。这也是为什么这些东西感觉被加入一些额外东东的原因。因为它就是被加入了额外东东。

 

获取类的元数据   通过调用如下的类方法你就可以获取到一个对象的类的元数据:

  1. Class c = [self class];  

   该方法既是实例方法也是类方法。它返回一个带有很多神奇信息的C构造体,比如实例变量、方法等等。所有这些和java.lang.reflect包相比都有些过时了,利用Objective-C访问这些信息的接口看起来很复杂。这可能就是故意设计成这样来“过滤”一些不合格的程序员。目前为止我唯一使用这些的地方就是为下面将要介绍的isKindOfClass:方法提供参数。一直以来我都不需要去窥视类结构的内容。

 

动态方程调用   我已经在方法调用一文中介绍了反射的一个方面。这使得你可以在运行时创建一个方法调用并传入参数。这和Java中使用java.lang.reflect.Method类很相似。

检查继承关系

   Java有一个名为instanceof的操作符可以用来检查一个对象是否是一个特定类或者接口的实例。Objective-C也有类似的功能,就是通过isKindOfClass:方法。isKindOfClass:会在消息接收者是指定类及其子类的实例的情况下返回YES。比如有一个关联的指针数组,这样就可以根据其类型进行不同的操作:


	for(BaseClass* base in myArray) {  
	if([base isKindOfClass:[ClassOne class]]) {  
	     // do stuff specific to ClassOne  
	}   
	else if([base isKindOfClass:[ClassTwo class]]) {  
	     // do stuff specific to ClassTwo  
	}  
	else if([base isKindOfClass:[ClassThree class]]) {  
	     // do stuff specific to ClassThree  
	}    
	}  

   如果你需要一个精确的类匹配,而不是匹配任何继承类,你就可以使用isMemberOfClass:方法。

 

检查是否符合协议   和实例检查类似,你可以测试一个对象是否符合特定的协议。Java在类和接口的情况下都使用instanceof方法搞定,但Objective-C使用了一个更笨重的方法。在测试是否合规的时候,应该使用conformsToProtocol:方法:

  1. BOOL conforms = [obj conformsToProtocol:@protocol(MyInterface)];  

检查方法是否存在   对于像我这样Java和C++的老手来说,如果不知道一个对象是否实现了一个方法就很奇怪了。但是Objective-C的类很大程度上是动态的,你就需要检查你需要的方法是否存在。这就需要respondsToSelector:方法。如下代码就是检查接收者是否实现(或者继承)了指定方法:

  1. if([obj respondsToSelector:@selector(aMethod:)]) { // it's there, so we can call it [obj aMethod:YES]; }  

   当然,利用Objective-C的反射你可以做更多的事情,这里我只是尝试谈谈反射机制最常见的应用。如果你需要在你的软件中加入核心的动态特性,你就需要熟悉下这些文档:Runtime Programming Guide:Introduction Runtime Reference


Objective-C反射机制

Objective-C反射机制
  • yangmeng13930719363
  • yangmeng13930719363
  • 2015年07月26日 14:36
  • 1329

利用Objective-C的反射机制和运行时特性实现类静态方法的动态访问(一)

利用Objective-C的反射机制和运行时特性实现类静态方法的动态访问,解决不能使用NSObject类的反射方法 performSelector 访问静态方法的坑爹问题!...
  • liyun_1981
  • liyun_1981
  • 2015年01月13日 21:00
  • 1543

利用Objective-C的反射机制和运行时特性实现类静态方法的动态访问(二)

继上次的研究成果继续深入研究,洒家又完善了下在运行时动态调用所有OC类方法的公用方法: typedef void*(*ObjcMsgSend)(id, SEL, ...); - (void *)in...
  • liyun_1981
  • liyun_1981
  • 2015年03月27日 15:27
  • 1010

Objective-C 获取控件 详解

1> 通过 IBOutlet 连接来获取控件 2> Tag 属性获取控件 在属性面板中,设置组件 Tag 的值,设置唯一的Tag 值 通过 UIView 的 view...
  • chenshun123
  • chenshun123
  • 2016年08月19日 10:02
  • 803

objective-c 反射

使用很简单,直接上代码 #import #import @interface Car : NSObject @end @implementation Car -(void)mov...
  • qq909157370
  • qq909157370
  • 2015年09月20日 16:59
  • 2346

Objective-c 反射

Class test = NSClassFromString(@"TestBean");         id obj = [[test alloc]init]; //        Class ...
  • zj7758
  • zj7758
  • 2012年03月01日 12:16
  • 2259

iOS开发:Object-C的反射机制

一、简介 动态编程机制可以让Object-C语言更加灵活,Object-C提供了3种编程方式与运行环境交互。 1.直接通过Object-C的源代码。这是最常见的方式 2.通过NSObject类中...
  • gongwutianya
  • gongwutianya
  • 2016年06月15日 13:18
  • 358

Objective-C的反射

我第一次接触Java的时候就觉得整个反射包都很新颖,它使得Java和解释型的脚本语言更接近了,与此同时也拉开了和主流的C和C++的距离。在运行时可以窥视到一个对象的类元数据真的很不可思议,尽管这些可能...
  • birthmarkqiqi
  • birthmarkqiqi
  • 2015年11月02日 16:26
  • 175

Objective-C中的反射和反射工厂

程序中可能会出现大量的if-else或者switch-case来选择一系列类中的某个类进行操作,利用反射(Reflection)就可以避免这些重复判断工作。   反射在Java中封装了类来实现,...
  • chaoyuan899
  • chaoyuan899
  • 2014年03月14日 00:22
  • 2474

objective-c ios iphone 反射

介绍objective-c 利用 反射 动态创建对象
  • jxncwzb
  • jxncwzb
  • 2011年05月06日 10:51
  • 2662
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Objective-C的反射
举报原因:
原因补充:

(最多只允许输入30个字)