黑马程序员-14-Objective-C学习笔记(反射)

---------------------- Java培训.Net培训Android培训IOS培训、期待与您交流! ----------------------

1.  简介

    概念 : 指程序可以访问、检测和修改它本身状态或行为的一种能力。在java中对反射已经有一个感性的认识 : 

        (1) 可以通过一些字符串来创建一个类的实例

        (2) 可以判断实例的继承结构

        (3) 可以通过字符串来调用对象的方法

       (4) 可以检查成员变量的类型,值等等。

     OC中的反射特性大部分来自于NSObject,和Foundation定义的一些函数。那么在OC中对象实例是通过类对象的实例来创建的,

     那么创建对象可以分为两步 :

        (1) 根据字符串获取类对象

        (2) 利用类对象来实例化对象

2. 使用

/*************************************        Person.h        ********************************************/
// Person.m省略
#import <Foundation/Foundation.h>

@interface Person : NSObject
@property (nonatomic,assign) int age;
@end

/*************************************        Student.h        ********************************************/
#import "Person.h"
// 定义一个协议
@protocol TestDelegate <NSObject>
- (void) sayHello;
@end

// 遵守该协议
@interface Student : Person <TestDelegate>
@property (nonatomic,strong) NSString *name;
@end

/*************************************        Student.m        ********************************************/
#import "Student.h"

@implementation Student

-(void)sayHello
{
    NSLog(@"hello,my name is %@ ,age is %d",_name,[self age]);
}

@end

/*************************************        main.m        ********************************************/
// 默认开启ARC
#import <Foundation/Foundation.h>
#import "Person.h"
#import "Student.h"

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        // 通常我们创建一个对象都是使用以下方法
        // Person *p = [[Person alloc] init];
 /**************************已知一个字符串创建一个实例*****************************/
        // 获取类对象
        Class personClass = NSClassFromString(@"Person");
        // 利用类对象创建实例
        Person *p = [[personClass alloc] init];
        // 访问实例的方法
        p.age = 10;
        NSLog(@"age = %d",p.age);
        
/*********************************检查继承关系************************************/
        Student *s = [[Student alloc] init];
        s.name = @"Mike";
        s.age = 10;
        
        // 模糊检查 : 对于属于该类或者该类的子类的实例都成立
        if ( [s isKindOfClass:personClass] ) {
            NSLog(@"Student is a kindof class of Person");
        }
        
        // 精确检查 : 只成立于属于该类的实例,对于子类实例不成立
        if ( [s isMemberOfClass:personClass] ) {
            NSLog(@"s is an instanceof Person");
        } else if ( [p isMemberOfClass:personClass] ){
            NSLog(@"p is an instanceof Person");
        }

/*********************************方法的检查************************************/
        // 通过字符串创建一个SEL对象
        SEL setAge = NSSelectorFromString(@"setAge:");
        // 判断该对象是否含有 setAge: 这个方法
        if ( [s respondsToSelector:setAge] ) {
            NSLog(@"s has a method name setAge:");
        }
        
        // 方法调用
        // 直接调用
        [s setName:@"mike"];
        // 间接调用
        [s performSelector:setAge withObject:@"Mike"];
/*********************************协议的检查************************************/
        Protocol *test = NSProtocolFromString(@"TestDelegate");
        // 检查是否遵守某个协议
        if ( [s conformsToProtocol:test] ) {
            NSLog(@"s has comfirm the protocol : TestDelegate");
        }
        // 检查是否存在协议中的你某个方法
        if ( ![s respondsToSelector:test] ) {
            NSLog(@"Student没有实现test这个方法");
        }
    }
    return 0;
}

    

3. 总结

    (1) 通过字符串获取对象一些运行时的信息通常都是 NS...FromString(NSString *)(例如 : NSStringFromClass,NSSelectorFromString等等)

    (2) 判断对象的继承的关系关键方法 : [obj isKindOfClass:aClass],可以判断子类; [obj isMemberOfClass:aClass],精确判断,不能用于判断子类

    (3) 判断对象是否遵守某个协议关键方法 : [obj conformsToProtocol:aSel];



---------------------- Java培训、.Net培训、Android培训、IOS培训、期待与您交流! ---------------------- 

 详情请查看:http://edu.csdn.net/heima



你可能感兴趣的:(黑马程序员-14-Objective-C学习笔记(反射))