zoukankan      html  css  js  c++  java
  • Objective-C的反射

          

    根类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。比如有一个关联的指针数组,这样就可以根据其类型进行不同的操作:

    [cpp] view plain copy
    1. for(BaseClass* base in myArray) {    
    2. if([base isKindOfClass:[ClassOne class]]) {    
    3.      // do stuff specific to ClassOne    
    4. }     
    5. else if([base isKindOfClass:[ClassTwo class]]) {    
    6.      // do stuff specific to ClassTwo    
    7. }    
    8. else if([base isKindOfClass:[ClassThree class]]) {    
    9.      // do stuff specific to ClassThree    
    10. }      
    11. }    

       如果你需要一个精确的类匹配,而不是匹配任何继承类,你就可以使用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

  • 相关阅读:
    C#文件操作
    C# 本地txt文件读取至comboBox下拉列表
    自动部署war包脚本
    设置eclipse包资源管理器的背景色
    Failed to connect to ourself!错误解决办法
    Keepalived+LVS+MysqlCluster(7.1.10)架构方案(一)
    Mysql Cluster在线添加数据节点
    在Linux下使用perl通过unixODBC连接SQLServer2000
    MySQL中四舍五入的实现
    关于Temporary error: 1218错误的思考
  • 原文地址:https://www.cnblogs.com/iOS-mt/p/5784286.html
Copyright © 2011-2022 走看看