zoukankan      html  css  js  c++  java
  • (转载)ObjectiveC反射实例

    Objective-C语法之动态类型(isKindOfClass, isMemberOfClass,id)等

    对象在运行时获取其类型的能力称为内省。内省可以有多种方法实现。

    判断对象类型

    -(BOOL) isKindOfClass: classObj判断是否是这个类或者这个类的子类的实例

    -(BOOL) isMemberOfClass: classObj 判断是否是这个类的实例

    我们试试这两个方法的使用。

    1、新建Person类继承NSObject,新建Teacher类继承Person

    1.1、新建Person类
    1. #import <Foundation/Foundation.h>
    2. @interface Person : NSObject  
    3. {  
    4.     NSString *name;  
    5. }  
    6. -(void)setName:(NSString*)n;  
    7. @end 
    1. #import "Person.h"
    2. @implementation Person  
    3. -(void)setName:(NSString *)n  
    4. {  
    5.     name = n;  
    6. }  
    7. @end 
    1.2新建Teacher类
    1. #import "Person.h"
    2. @interface Teacher : Person  
    3. -(void)teach;  
    4. @end 
    1. #import "Teacher.h"
    2. @implementation Teacher  
    3. -(void)teach  
    4. {  
    5.     NSLog(@"我教数学");  
    6. }  
    7. @end 
    1.3 我们先实验下isMemberOfClass方法。
    1. NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];  
    2.    Person *person = [[Person alloc] init];  
    3.    Teacher *teacher = [[Teacher alloc] init];  
    4. //YES
    5. if ([teacher isMemberOfClass:[Teacher class]]) {  
    6.         NSLog(@"teacher Teacher类的成员");  
    7.    }  
    8. //NO
    9. if ([teacher isMemberOfClass:[Person class]]) {  
    10.        NSLog(@"teacher Person类的成员");  
    11.    }  
    12. //NO
    13. if ([teacher isMemberOfClass:[NSObject class]]) {  
    14.        NSLog(@"teacher NSObject类的成员");  
    15.    }  
    16.    [person release];  
    17.    [teacher release];  
    18.    [pool release]; 

    打印结果:

    2012-07-04 14:23:07.965 ObjectiveCTest[2460:f803] teacher Teacher类的成员

    只有第一个判断打印出来,isMemberOfClass判断是否是属于这类的实例,是否跟父类有关系他不管。

    1.4 isMemberOfClass方法
    1. NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];  
    2. Person *person = [[Person alloc] init];  
    3. Teacher *teacher = [[Teacher alloc] init];  
    4. //YES
    5. if ([teacher isKindOfClass:[Teacher class]]) {  
    6.     NSLog(@"teacher 是 Teacher类或Teacher的子类");  
    7. }  
    8. //YES
    9. if ([teacher isKindOfClass:[Person class]]) {  
    10.     NSLog(@"teacher 是 Person类或Person的子类");  
    11. }  
    12. //YES
    13. if ([teacher isKindOfClass:[NSObject class]]) {  
    14.     NSLog(@"teacher 是 NSObject类或NSObject的子类");  
    15. }  
    16. [person release];  
    17. [teacher release];  
    18. [pool release]; 

    2012-07-04 14:34:17.315 ObjectiveCTest[2595:f803] teacher Teacher类或Teacher的子类

    2012-07-04 14:34:17.316 ObjectiveCTest[2595:f803] teacher Person类或Person的子类

    2012-07-04 14:34:17.316 ObjectiveCTest[2595:f803] teacher NSObject类或NSObject的子类

    三个结果都打印出来了。

    2、

    -(BOOL) respondsToSelector: selector 判读实例是否有这样方法

    +(BOOL) instancesRespondToSelector:  判断类是否有这个方法。此方法是类方法,不能用在类的对象

    2.1 respondsToSelector的使用

    这里不写对象的创建和释放了,参考上面的代码

    1. // YES
    2. if ( [teacher respondsToSelector: @selector( setName: )] == YES ) {  
    3.     NSLog(@"teacher responds to setSize: method" );  
    4. }  
    5. // NO
    6. if ( [teacher respondsToSelector: @selector( abcde )] == YES ) {  
    7.     NSLog(@"teacher responds to nonExistant method" );  
    8. }  
    9. // YES
    10. if ( [Teacher respondsToSelector: @selector( alloc )] == YES ) {  
    11.     NSLog(@"teacher class responds to alloc method\n" );  

    打印结果:

    2012-07-04 14:39:49.853 ObjectiveCTest[2723:f803] teacher responds to setSize: method

    2012-07-04 14:39:49.854 ObjectiveCTest[2723:f803] teacher class responds to alloc method

    中间的那个判断我随便写了个selector,当然没有了。respondsToSelector 检查类方法 alloc返回YES

    2.2 instancesRespondToSelector
    1. // NO
    2. if ( [Person instancesRespondToSelector: @selector(teach)] == YES ) {  
    3.         NSLog(@"Person instance responds to teach method" );  
    4.     }  
    5. // YES
    6. if ( [Teacher instancesRespondToSelector: @selector(teach)] == YES ) {  
    7.         NSLog(@"Teacher instance responds to teach method");  
    8.     }  
    9. // YES
    10. if ( [Teacher instancesRespondToSelector: @selector(setName:)] == YES ) {  
    11.         NSLog(@"Teacher instance responds to setName: method" );  
    12.     } 

    打印结果:

    1. 2012-07-04 14:52:29.378 ObjectiveCTest[2961:f803] Teacher instance responds to teach method  
    2. 2012-07-04 14:52:29.379 ObjectiveCTest[2961:f803] Teacher instance responds to setName: method 

    3、Objective-C的id类型

    C++ 使用的是强类型:对象必须符合其类型,否则不能通过编译。在 Objective-C 中,id类型类似于(void*) ,可以指向任何类的实例。而不需要强制转换。

    下面看看使用,

    先把Teacher类中的 teach方法修改一下,改成

    -(void)teach

    {

    NSLog(@"%@ 教数学" ,name);

    }

    然后实现并调用

    1. NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];  
    2. Person *person = [[Person alloc] init];  
    3. Teacher *teacher = [[Teacher alloc] init];  
    4. id p = person;  
    5. id t = teacher;  
    6. [t setName:@"张三老师"];  
    7. [t teach];  
    8. [person release];  
    9. [teacher release];  
    10. [pool release]; 

    打印结果:

    1. 2012-07-04 14:57:55.905 ObjectiveCTest[3085:f803] 张三老师 教数学

    来自:http://www.linuxidc.com/Linux/2012-07/64453.htm

    本人的上机验证:

    有一个类Words,里面有一个display方法(words+subOf是words的category)

    image

    使用respondsToSelector发现并没有这个方法,奇怪,问题在哪儿?

    image

    原来是display后面多了一个冒号,去掉以后正常了,这个和在action里面使用的时候不一样?

    image

  • 相关阅读:
    笔记44 Hibernate快速入门(一)
    tomcat 启用https协议
    笔记43 Spring Security简介
    笔记43 Spring Web Flow——订购披萨应用详解
    笔记42 Spring Web Flow——Demo(2)
    笔记41 Spring Web Flow——Demo
    Perfect Squares
    Factorial Trailing Zeroes
    Excel Sheet Column Title
    Excel Sheet Column Number
  • 原文地址:https://www.cnblogs.com/angestudy/p/2623321.html
Copyright © 2011-2022 走看看