8、OC中的“反射”

来源:互联网 发布:德州农工大学 知乎 编辑:程序博客网 时间:2024/05/07 00:04

代码中用到的类

Person.h

#import <Foundation/Foundation.h>@interface Person : NSObject+(void)speak;@end
Person.m
#import "Person.h"@implementation Person+(void)speak{    NSLog(@"I'm a person!");}@end
Student.h
#import "Person.h"@interface Student : Person{    int age;}-(Student *)initAge:(int)age;-(void)setAge:(int)age;-(void)setAge1:(NSString *)age;-(int)age;@end
Student.m
#import "Student.h"@implementation Student-(Student *)initAge:(int)age{    self = [super init];    if(self){        self->age = age;    }    return self;}-(void)setAge:(int)age{    self->age = age;}//这里是为了反射调用时作准备-(void)setAge1:(NSString *)age{    self->age = [age intValue];}-(int)age{    return age;}@end

1、类的反射【实例化对象】
        Class name = NSClassFromString(@"Student");        Student *stu = [[name alloc] init];        NSLog(@"%@",stu);
2、-(BOOL)isKindOfClass:(Class)aClass; 判断对象是不是属于指定类型或其子类   

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

    Student *stu = [[Student alloc]init];        if([stu isKindOfClass:[Person class]]){        NSLog(@"stu是Person类型或其子类");    }else{        NSLog(@"stu不是Person类型或其子类");    }        if([stu isMemberOfClass:[Person class]]){        NSLog(@"stu是Person类型");    }else{        NSLog(@"stu不是Person类型");    }
4、- (BOOL)respondsToSelector:(SEL)aSelector  判断类型或对象有没有某个方法

判断Person类型

        if ([Person respondsToSelector:@selector(speak)]) {            NSLog(@"Person 有speak这个方法");        }else{            NSLog(@"没有");        }

判断Student对象   

        Student *stu = [[Student alloc]init];        if([stu respondsToSelector:@selector(setAge)]){            NSLog(@"stu 有setAge这个方法");        }else{            NSLog(@"没有");        }
输出结果:

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

Program ended with exit code: 0

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

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

如上面代码这样写就对了

        Student *stu = [[Student alloc]init];        if([stu respondsToSelector:@selector(<span style="color:#ff0000;">setAge:</span>)]){//此处有:            NSLog(@"stu 有setAge这个方法");        }else{            NSLog(@"没有");        }

*技巧

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

        Student *stu = [[Student alloc]init];        SEL sel =  NSSelectorFromString(@"setAge:");        if([stu respondsToSelector:sel]){            NSLog(@"stu 有setAge这个方法");        }else{            NSLog(@"没有");        }

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

调用无参有返回值的

        Student *stu = [[Student alloc]initAge:1];        int age = [stu performSelector:@selector(age)];        NSLog(@"%i",age);//输出1
调用有参无返回值的
        Student *stu = [[Student alloc]initAge:1];        //[stu  performSelector:@selector(setAge:) withObject:1];////这是语法报错        [stu  performSelector:@selector(setAge1:) withObject:@"2"];        NSLog(@"%i",stu.age);

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

typedeflong NSInteger;

敲打也是基本类型

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


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

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


0 0
原创粉丝点击