8、OC中的“反射”

http://blog.csdn.net/victormokai/article/details/19631359


代码中用到的类

Person.h

[objc]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. #import <Foundation/Foundation.h>  
  2.   
  3. @interface Person : NSObject  
  4. +(void)speak;  
  5. @end  
Person.m
[objc]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. #import "Person.h"  
  2.   
  3. @implementation Person  
  4. +(void)speak{  
  5.     NSLog(@"I'm a person!");  
  6. }  
  7. @end  
Student.h
[objc]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. #import "Person.h"  
  2.   
  3. @interface Student : Person{  
  4.     int age;  
  5. }  
  6. -(Student *)initAge:(int)age;  
  7. -(void)setAge:(int)age;  
  8. -(void)setAge1:(NSString *)age;  
  9. -(int)age;  
  10. @end  
Student.m
[objc]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. #import "Student.h"  
  2.   
  3. @implementation Student  
  4.   
  5. -(Student *)initAge:(int)age{  
  6.     self = [super init];  
  7.     if(self){  
  8.         self->age = age;  
  9.     }  
  10.     return self;  
  11. }  
  12.   
  13. -(void)setAge:(int)age{  
  14.     self->age = age;  
  15. }  
  16.   
  17. //这里是为了反射调用时作准备  
  18. -(void)setAge1:(NSString *)age{  
  19.     self->age = [age intValue];  
  20. }  
  21.   
  22.   
  23. -(int)age{  
  24.     return age;  
  25. }  
  26. @end  

1、类的反射【实例化对象】
[objc]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. Class name = NSClassFromString(@"Student");  
  2. Student *stu = [[name alloc] init];  
  3. NSLog(@"%@",stu);  
2、- (BOOL)isKindOfClass:(Class)aClass; 判断对象是不是属于指定类型或其子类   

3、- (BOOL)isMemberOfClass:(Class)aClass 判断对象是不是属于指定类型

[objc]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. Student *stu = [[Student alloc]init];  
  2.   
  3. if([stu isKindOfClass:[Person class]]){  
  4.     NSLog(@"stu是Person类型或其子类");  
  5. }else{  
  6.     NSLog(@"stu不是Person类型或其子类");  
  7. }  
  8.   
  9. if([stu isMemberOfClass:[Person class]]){  
  10.     NSLog(@"stu是Person类型");  
  11. }else{  
  12.     NSLog(@"stu不是Person类型");  
  13. }  
4、- (BOOL)respondsToSelector:(SEL)aSelector  判断类型或对象有没有某个方法

判断Person类型

[objc]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. if ([Person respondsToSelector:@selector(speak)]) {  
  2.     NSLog(@"Person 有speak这个方法");  
  3. }else{  
  4.     NSLog(@"没有");  
  5. }  

判断Student对象   

[objc]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. Student *stu = [[Student alloc]init];  
  2. if([stu respondsToSelector:@selector(setAge)]){  
  3.     NSLog(@"stu 有setAge这个方法");  
  4. }else{  
  5.     NSLog(@"没有");  
  6. }  
输出结果:

2014-02-21 17:51:06.632反射[7483:303]没有

Program ended with exit code: 0

惊恐什么情况,Student明明有setAge这个方法,怎么会输出没有!

这里需要注意,OC的方法当有参数时,: 双冒号也是属于方法名的一部分

如上面代码这样写就对了

[objc]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. Student *stu = [[Student alloc]init];  
  2. if([stu respondsToSelector:@selector(setAge:)]){//此处有:  
  3.     NSLog(@"stu 有setAge这个方法");  
  4. }else{  
  5.     NSLog(@"没有");  
  6. }  

*技巧

上面的@selector(xxx)还可以通过字符串动态生成 

[objc]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. Student *stu = [[Student alloc]init];  
  2. SEL sel =  NSSelectorFromString(@"setAge:");  
  3. if([stu respondsToSelector:sel]){  
  4.     NSLog(@"stu 有setAge这个方法");  
  5. }else{  
  6.     NSLog(@"没有");  
  7. }  

5、- (id)performSelector:(SEL)aSelector  动态调用对象的方法

调用无参有返回值的

[objc]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. Student *stu = [[Student alloc]initAge:1];  
  2. int age = [stu performSelector:@selector(age)];  
  3. NSLog(@"%i",age);//输出1  
调用有参无返回值的
[objc]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. Student *stu = [[Student alloc]initAge:1];  
  2. //[stu  performSelector:@selector(setAge:) withObject:1];这是语法报错  
  3. [stu  performSelector:@selector(setAge1:) withObject:@"2"];  
  4. NSLog(@"%i",stu.age);  

第二行是无效的,因为参数必须是对象,有人说,用int的包装类型NSInteger不就行了,我们去源码去看下,

typedeflong NSInteger;

敲打也是基本类型

那怎么办,所以我们就先用NSString先传进去,然后再转回来


6、- (BOOL)conformsToProtocol:(Protocol *)aProtocol; 判断对象是否实现某个Protocol协议

这个就不写代码了,手冷。。。。大笑



    • 0
      点赞
    • 0
      收藏
      觉得还不错? 一键收藏
    • 0
      评论

    “相关推荐”对你有帮助么?

    • 非常没帮助
    • 没帮助
    • 一般
    • 有帮助
    • 非常有帮助
    提交
    评论
    添加红包

    请填写红包祝福语或标题

    红包个数最小为10个

    红包金额最低5元

    当前余额3.43前往充值 >
    需支付:10.00
    成就一亿技术人!
    领取后你会自动成为博主和红包主的粉丝 规则
    hope_wisdom
    发出的红包
    实付
    使用余额支付
    点击重新获取
    扫码支付
    钱包余额 0

    抵扣说明:

    1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
    2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

    余额充值